re PR c++/71248 (crash on in-class initializer of array of pointer to member)
authorPaolo Carlini <paolo@gcc.gnu.org>
Tue, 31 May 2016 17:17:29 +0000 (17:17 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 31 May 2016 17:17:29 +0000 (17:17 +0000)
/cp
2016-05-31  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/71248
* decl.c (check_static_variable_definition): Use DECL_SOURCE_LOCATION
to obtain correct locations; avoid redundant diagnostics on
out-of-class definitions.

/testsuite
2016-05-31  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/71248
* g++.dg/cpp0x/pr71248.C: New.
* g++.dg/cpp0x/auto7.C: Test column numbers too.
* g++.dg/cpp0x/constexpr-static8.C: Likewise.
* g++.dg/init/new37.C: Likewise.
* g++.dg/template/static1.C: Likewise.
* g++.dg/template/static2.C: Likewise.

From-SVN: r236931

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/auto7.C
gcc/testsuite/g++.dg/cpp0x/constexpr-static8.C
gcc/testsuite/g++.dg/cpp0x/pr71248.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/new37.C
gcc/testsuite/g++.dg/template/static1.C
gcc/testsuite/g++.dg/template/static2.C

index 266ca0adcbe6097577f434d5a08d3c98045a2b92..0401255dad7c81a40d946f57b863fa92729e8fa3 100644 (file)
@@ -1,4 +1,11 @@
-2016-05-27  Martin Sebor  <msebor@redhat.com>
+2016-05-31  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/71248
+       * decl.c (check_static_variable_definition): Use DECL_SOURCE_LOCATION
+       to obtain correct locations; avoid redundant diagnostics on
+       out-of-class definitions.
+
+2016-05-30  Martin Sebor  <msebor@redhat.com>
 
        PR c++/71306
        * init.c (warn_placement_new_too_small): Handle placement new arguments
index ef5fd665b4632b1d2e3ae359fb0b3e139cf653fc..cbbb84b9d0c18a0ef6d1d56cd538ca7015a8abbd 100644 (file)
@@ -8581,6 +8581,9 @@ build_ptrmem_type (tree class_type, tree member_type)
 static int
 check_static_variable_definition (tree decl, tree type)
 {
+  /* Avoid redundant diagnostics on out-of-class definitions.  */
+  if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type))
+    return 0;
   /* Can't check yet if we don't know the type.  */
   if (dependent_type_p (type))
     return 0;
@@ -8591,15 +8594,17 @@ check_static_variable_definition (tree decl, tree type)
   else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       if (!COMPLETE_TYPE_P (type))
-       error ("in-class initialization of static data member %q#D of "
-              "incomplete type", decl);
+       error_at (DECL_SOURCE_LOCATION (decl),
+                 "in-class initialization of static data member %q#D of "
+                 "incomplete type", decl);
       else if (literal_type_p (type))
-       permerror (input_location,
+       permerror (DECL_SOURCE_LOCATION (decl),
                   "%<constexpr%> needed for in-class initialization of "
                   "static data member %q#D of non-integral type", decl);
       else
-       error ("in-class initialization of static data member %q#D of "
-              "non-literal type", decl);
+       error_at (DECL_SOURCE_LOCATION (decl),
+                 "in-class initialization of static data member %q#D of "
+                 "non-literal type", decl);
       return 1;
     }
 
@@ -8611,17 +8616,20 @@ check_static_variable_definition (tree decl, tree type)
      required.  */
   if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
     {
-      error ("invalid in-class initialization of static data member "
-            "of non-integral type %qT",
-            type);
+      error_at (DECL_SOURCE_LOCATION (decl),
+               "invalid in-class initialization of static data member "
+               "of non-integral type %qT",
+               type);
       return 1;
     }
   else if (!CP_TYPE_CONST_P (type))
-    error ("ISO C++ forbids in-class initialization of non-const "
-          "static member %qD",
-          decl);
+    error_at (DECL_SOURCE_LOCATION (decl),
+             "ISO C++ forbids in-class initialization of non-const "
+             "static member %qD",
+             decl);
   else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
-    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids initialization of member constant "
+    pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
+            "ISO C++ forbids initialization of member constant "
             "%qD of non-integral type %qT", decl, type);
 
   return 0;
index 2cf6a94a4002f80f5767befaf3ebd25653854d8f..cc1624fc366b5953aea03e553686b93062096807 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-31  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/71248
+       * g++.dg/cpp0x/pr71248.C: New.
+       * g++.dg/cpp0x/auto7.C: Test column numbers too.
+       * g++.dg/cpp0x/constexpr-static8.C: Likewise.
+       * g++.dg/init/new37.C: Likewise.
+       * g++.dg/template/static1.C: Likewise.
+       * g++.dg/template/static2.C: Likewise.
+
 2016-05-31  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/i386/avx512vl-vbroadcast-3.c: Scan %\[re\]di
index c213c747bb3e3fe6f1f9937292933dc77755c299..99685d33375e4f7bda5fe79ee0184bf0103b498b 100644 (file)
@@ -7,7 +7,7 @@ auto j;                 // { dg-error "has no initializer" }
 
 template<int> struct A
 {
-  static auto k = 7;   // { dg-error "non-const" }
+  static auto k = 7;   // { dg-error "15:ISO C\\+\\+ forbids" }
   static auto l;       // { dg-error "has no initializer" }
   auto m;              // { dg-error "non-static data member declared" }
 };
index 34aa5afc001206504983eea887bf87331f06afe5..9facd0fe33d1be26883fe0e6634926d80dc0d8a9 100644 (file)
@@ -3,6 +3,6 @@
 // { dg-options "-fpermissive" }
 
 struct Foo {
-  static const double d = 3.14; // { dg-warning "constexpr" }
+  static const double d = 3.14; // { dg-warning "23:'constexpr' needed" }
 };
-const double Foo::d;            // { dg-warning "constexpr" }
+const double Foo::d;
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71248.C b/gcc/testsuite/g++.dg/cpp0x/pr71248.C
new file mode 100644 (file)
index 0000000..e996351
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/71248
+// { dg-do compile { target c++11 } }
+
+struct S
+{
+    int a;
+    static int S::*typeMembers[] = {  // { dg-error "20:in-class initialization" }
+        &S::a,
+    };
+};
index eab7854217454fd36127a578ee8391268412ffea..734b1419128e64503124d9d3cc13718c764fdbdc 100644 (file)
@@ -40,7 +40,8 @@ struct T1 {
 };
 
 struct T2 {
-  static const double n = 2; // { dg-error "non-integral type" }
+  static const double n = 2; // { dg-error "23:'constexpr' needed" "" { target c++11 } }
+  // { dg-error "23:ISO C\\+\\+ forbids" "" { target c++98_only } 43 }
 };
 
 struct T3 {
index 98e1acb9e510921f0d26d6e60b6d1b77a7a87043..76736acdb21ed67fa14b17956e03b35a72735d8b 100644 (file)
@@ -1,4 +1,6 @@
 template <typename T> struct A
 {
-  static const int t[1][1]={{0}}; // { dg-error "brace-enclosed|in-class" }
+  static const int t[1][1]={{0}}; // { dg-error "20:'constexpr' needed" "" { target c++11 } }
+  // { dg-error "20:invalid in-class" "" { target c++98_only } 3 }
+  // { dg-error "28:a brace-enclosed" "" { target c++98_only } 3 }
 };
index 881f07ce95a0b21f1fcafca70821f96f68e707cc..d8ce087d229d42f980a1703dc733f7ff5ba44244 100644 (file)
@@ -4,7 +4,9 @@ template<int A::* P>
 class B
 {
 public:
-  static int A::* const p = P; // { dg-error "" }
+  static int A::* const p = P; // { dg-error "25:'constexpr' needed" "" { target c++11 } }
+  // { dg-error "25:invalid in-class" "" { target c++98_only } 7 }
+  // { dg-error "29:template parameter" "" { target c++98_only } 7 }
 };
 
 class A