re PR c++/16338 (ICE when throwing a compound literal)
authorMark Mitchell <mark@codesourcery.com>
Mon, 2 Aug 2004 01:58:52 +0000 (01:58 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 2 Aug 2004 01:58:52 +0000 (01:58 +0000)
PR c++/16338
* cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro.
* call.c (null_ptr_cst_p): Handle variables with constant
initializers.
* pt.c (convert_nontype_argument): Use
DECL_INTEGRAL_CONSTANT_VAR_P.
* semantics.c (finish_id_expression): Likewise.

PR c++~/16489
* decl.c (duplicate_decls): Reject duplicate namespace
declarations.

PR c++/16810
* typeck.c (build_ptrmemfunc): Loosen assertion.

PR c++/16338
* g++.dg/init/null1.C: New test.
* g++.dg/tc1/dr76.C: Adjust error marker.

PR c++/16489
* g++.dg/parse/namespace10.C: New test.

PR c++/16810
* g++.dg/inherit/ptrmem2.C: New test.

From-SVN: r85421

12 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/ptrmem2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/null1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/namespace10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tc1/dr76.C

index 6122d57b95a07986816dbbee63870684135c7d1f..da833d1762a688a8eda6a11df5f03340c3cbe7b5 100644 (file)
@@ -1,3 +1,20 @@
+2004-08-01  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16338
+       * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro.
+       * call.c (null_ptr_cst_p): Handle variables with constant
+       initializers.
+       * pt.c (convert_nontype_argument): Use
+       DECL_INTEGRAL_CONSTANT_VAR_P.
+       * semantics.c (finish_id_expression): Likewise.
+
+       PR c++~/16489
+       * decl.c (duplicate_decls): Reject duplicate namespace
+       declarations.
+
+       PR c++/16810
+       * typeck.c (build_ptrmemfunc): Loosen assertion.
+
 2004-08-01  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * call.c (z_candidate::template_decl): Rename from template.
index a6bfc729352389bdc83883f4a3fa96efc4ccca48..a34eb271001bf47661fd261509352405b1268bad 100644 (file)
@@ -429,6 +429,9 @@ struct z_candidate {
   z_candidate *next;
 };
 
+/* Returns true iff T is a null pointer constant in the sense of
+   [conv.ptr].  */
+
 bool
 null_ptr_cst_p (tree t)
 {
@@ -436,13 +439,14 @@ null_ptr_cst_p (tree t)
 
      A null pointer constant is an integral constant expression
      (_expr.const_) rvalue of integer type that evaluates to zero.  */
+  if (DECL_INTEGRAL_CONSTANT_VAR_P (t))
+    t = decl_constant_value (t);
   if (t == null_node
       || (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
     return true;
   return false;
 }
 
-
 /* Returns nonzero if PARMLIST consists of only default parms and/or
    ellipsis.  */
 
index 8d14911235d56df59240aaf15f2f7f310ca12273..cdb67063f3ae773260f39d98b03d8fb077ce7c54 100644 (file)
@@ -1821,6 +1821,23 @@ struct lang_decl GTY(())
 #define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
   (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
 
+/* Nonzero for a VAR_DECL that can be used in an integral constant
+   expression.    
+
+      [expr.const]
+
+      An integral constant-expression can only involve ... const
+      variables of static or enumeration types initialized with
+      constant expressions ...
+  
+   The standard does not require that the expression be non-volatile.
+   G++ implements the proposed correction in DR 457.  */
+#define DECL_INTEGRAL_CONSTANT_VAR_P(NODE)             \
+  (TREE_CODE (NODE) == VAR_DECL                                \
+   && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (NODE))  \
+   && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (NODE))        \
+   && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (NODE))
+
 /* Nonzero if the DECL was initialized in the class definition itself,
    rather than outside the class.  This is used for both static member
    VAR_DECLS, and FUNTION_DECLS that are defined in the class.  */
index c84c4be7687fe9e36fc8f1196dd7d3a77f89143e..c4755c0c7b042efd919cc2f94699c2ca6eef8d5b 100644 (file)
@@ -1407,19 +1407,32 @@ duplicate_decls (tree newdecl, tree olddecl)
     /* One of the declarations is a template instantiation, and the
        other is not a template at all.  That's OK.  */
     return NULL_TREE;
-  else if (TREE_CODE (newdecl) == NAMESPACE_DECL
-           && DECL_NAMESPACE_ALIAS (newdecl)
-           && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
-    /* In [namespace.alias] we have:
-
-        In a declarative region, a namespace-alias-definition can be
-        used to redefine a namespace-alias declared in that declarative
-        region to refer only to the namespace to which it already
-        refers.
-
-      Therefore, if we encounter a second alias directive for the same
-      alias, we can just ignore the second directive.  */
-    return olddecl;
+  else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
+    {
+      /* In [namespace.alias] we have:
+        
+           In a declarative region, a namespace-alias-definition can be
+          used to redefine a namespace-alias declared in that declarative
+          region to refer only to the namespace to which it already
+          refers.
+          
+        Therefore, if we encounter a second alias directive for the same
+        alias, we can just ignore the second directive.  */
+      if (DECL_NAMESPACE_ALIAS (newdecl)
+         && (DECL_NAMESPACE_ALIAS (newdecl) 
+             == DECL_NAMESPACE_ALIAS (olddecl)))
+       return olddecl;
+      /* [namespace.alias]
+
+         A namespace-name or namespace-alias shall not be declared as
+        the name of any other entity in the same declarative region.
+        A namespace-name defined at global scope shall not be
+        declared as the name of any other entity in any glogal scope
+        of the program.  */
+      error ("declaration of `namespace %D' conflicts with", newdecl);
+      cp_error_at ("previous declaration of `namespace %D' here", olddecl);
+      return error_mark_node;
+    }
   else
     {
       const char *errmsg = redeclaration_error_message (newdecl, olddecl);
index 0ecbda0fa1566acc4b59f46a39f6a13fee5a7506..ad4891049748a7910304f805c0eba403130eec28 100644 (file)
@@ -3233,9 +3233,7 @@ convert_nontype_argument (tree type, tree expr)
           will not return the initializer.  Handle that special case
           here.  */
        if (expr == const_expr
-           && TREE_CODE (expr) == VAR_DECL
-           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr)
-           && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr))
+           && DECL_INTEGRAL_CONSTANT_VAR_P (expr)
            /* DECL_INITIAL can be NULL if we are processing a
               variable initialized to an expression involving itself.
               We know it is initialized to a constant -- but not what
index 152d75ca1f0f9c22c36dcd7a72f7018e40904433..606fe5fc3f64793808e813c70b3cbbaa640a4c8e 100644 (file)
@@ -2564,25 +2564,15 @@ finish_id_expression (tree id_expression,
       /* Only certain kinds of names are allowed in constant
        expression.  Enumerators and template parameters 
        have already been handled above.  */
-      if (integral_constant_expression_p)
+      if (integral_constant_expression_p
+         && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
        {
-           /* Const variables or static data members of integral or
-             enumeration types initialized with constant expressions
-             are OK.  */
-         if (TREE_CODE (decl) == VAR_DECL
-             && CP_TYPE_CONST_P (TREE_TYPE (decl))
-             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
-             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
-           ;
-         else
+         if (!allow_non_integral_constant_expression_p)
            {
-             if (!allow_non_integral_constant_expression_p)
-               {
-                 error ("`%D' cannot appear in a constant-expression", decl);
-                 return error_mark_node;
-               }
-             *non_integral_constant_expression_p = true;
+             error ("`%D' cannot appear in a constant-expression", decl);
+             return error_mark_node;
            }
+         *non_integral_constant_expression_p = true;
        }
       
       if (TREE_CODE (decl) == NAMESPACE_DECL)
index cad077a13e2a088d7355503d08fce91b142350c7..bc458cad8d608a35179c116d0956312027414050 100644 (file)
@@ -5463,7 +5463,10 @@ build_ptrmemfunc (tree type, tree pfn, int force)
        }
 
       /* Just adjust the DELTA field.  */
-      my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727);
+      my_friendly_assert 
+       (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (delta),
+                                                   ptrdiff_type_node), 
+        20030727);
       if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
        n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
       delta = cp_build_binary_op (PLUS_EXPR, delta, n);
index 69ef9dc680e8c1a2c5074d907dc1b20f4b466144..c6ae76c89235764f58d3eab3b2f8544d21fd2e29 100644 (file)
@@ -1,3 +1,15 @@
+2004-08-01  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16338
+       * g++.dg/init/null1.C: New test.
+       * g++.dg/tc1/dr76.C: Adjust error marker.
+       
+       PR c++/16489
+       * g++.dg/parse/namespace10.C: New test.
+       
+       PR c++/16810
+       * g++.dg/inherit/ptrmem2.C: New test.
+
 2004-08-02  Ben Elliston  <bje@au.ibm.com>
 
        PR target/16155
diff --git a/gcc/testsuite/g++.dg/inherit/ptrmem2.C b/gcc/testsuite/g++.dg/inherit/ptrmem2.C
new file mode 100644 (file)
index 0000000..a137055
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/16810
+
+struct C {
+  virtual void f() {}
+};
+
+struct B {virtual ~B() {} };
+
+class D : public B, public C
+{
+public:
+  virtual void f() {}
+};
+
+typedef void ( C::*FP)();
+typedef void ( D::*D_f)();
+
+int main() {
+  D *d = new D();
+  C *c = d;
+
+  const FP fptr = (FP) &D::f;;
+  (d->* (D_f)fptr)();
+}
+
diff --git a/gcc/testsuite/g++.dg/init/null1.C b/gcc/testsuite/g++.dg/init/null1.C
new file mode 100644 (file)
index 0000000..37a9a3e
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/16338
+
+const int NULL = 0;
+int main() { 
+  double* p = NULL; 
+}
diff --git a/gcc/testsuite/g++.dg/parse/namespace10.C b/gcc/testsuite/g++.dg/parse/namespace10.C
new file mode 100644 (file)
index 0000000..aeaae61
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/16489
+
+namespace m {} // { dg-error "" }
+
+namespace n {
+  namespace m {}
+}
+
+namespace m = n::m; // { dg-error "" }
index 6d3d1c12a048680139b776ecc5f9684c21a943a0..0859b0c730eacf23127708d915d7194f82af6f02 100644 (file)
@@ -5,4 +5,4 @@
 volatile const int a = 5;
 
 template <int> struct K;
-template struct K<a>;  // { dg-error "non-constant" }
+template struct K<a>;  // { dg-error "" }