re PR c++/14545 (Cannot compile pooma-gcc (regression))
authorGiovanni Bajo <giovannibajo@gcc.gnu.org>
Fri, 19 Mar 2004 09:58:50 +0000 (09:58 +0000)
committerGiovanni Bajo <giovannibajo@gcc.gnu.org>
Fri, 19 Mar 2004 09:58:50 +0000 (09:58 +0000)
PR c++/14545
* parser.c (cp_parser_functional_cast): A cast to anything
but integral or enumaration type is not an integral constant
expression.
* pt.c (value_dependent_expression_p): Handle cast expressions
without operands (such as "int()").

PR c++/14545
* g++.dg/parse/template15.C: New test.

From-SVN: r79672

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/template15.C [new file with mode: 0644]

index 3822563923612062f2af6ff809f86c9e7cafde54..77e30a552889722164d4434f05e4099f37d0475c 100644 (file)
@@ -1,3 +1,12 @@
+2004-03-19  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       PR c++/14545
+       * parser.c (cp_parser_functional_cast): A cast to anything
+       but integral or enumaration type is not an integral constant
+       expression.
+       * pt.c (value_dependent_expression_p): Handle cast expressions
+       without operands (such as "int()").
+
 2004-03-18  Mark Mitchell  <mark@codesourcery.com>
 
        * semantics.c (finish_pseudo_destructor_expr): Allow differing
index c05e37542188fa013ca42285d4fe19265bb8b1cb..e964f48753f86e2c96389db3d4491e596cade44e 100644 (file)
@@ -14494,12 +14494,23 @@ static tree
 cp_parser_functional_cast (cp_parser* parser, tree type)
 {
   tree expression_list;
+  tree cast;
 
   expression_list
     = cp_parser_parenthesized_expression_list (parser, false,
                                               /*non_constant_p=*/NULL);
 
-  return build_functional_cast (type, expression_list);
+  cast = build_functional_cast (type, expression_list);
+  /* [expr.const]/1: In an integral constant expression "only type
+     conversions to integral or enumeration type can be used".  */
+  if (cast != error_mark_node && !type_dependent_expression_p (type) 
+      && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (type)))
+    {
+      if (cp_parser_non_integral_constant_expression 
+         (parser, "a call to a constructor"))
+       return error_mark_node;
+    }
+  return cast;
 }
 
 /* Save the tokens that make up the body of a member function defined
index 365cb18bf6688bcf7190f88df08ccbfcd90b01cd..3719410ad0dba23c623a4dbbb00aa8bb7b8b766d 100644 (file)
@@ -11776,10 +11776,21 @@ value_dependent_expression_p (tree expression)
       || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
       || TREE_CODE (expression) == CAST_EXPR)
     {
-      if (dependent_type_p (TREE_TYPE (expression)))
+      tree type = TREE_TYPE (expression);
+      if (dependent_type_p (type))
        return true;
       /* A functional cast has a list of operands.  */
       expression = TREE_OPERAND (expression, 0);
+      if (!expression)
+       {
+         /* If there are no operands, it must be an expression such
+            as "int()". This should not happen for aggregate types
+            because it would form non-constant expressions.  */
+         my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type), 
+                             20040318);
+
+         return false;
+       }
       if (TREE_CODE (expression) == TREE_LIST)
        {
          do
index 391bfa3844cbbd0d35faf7640a462f89d00a2baf..7ae25a39be68a0c7257f5d0d6cae26effad55f67 100644 (file)
@@ -1,3 +1,8 @@
+2004-03-19  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       PR c++/14545
+       * g++.dg/parse/template15.C: New test.
+
 2004-03-18  Mark Mitchell  <mark@codesourcery.com>
 
        * g++.dg/expr/dtor2.C: New test.
diff --git a/gcc/testsuite/g++.dg/parse/template15.C b/gcc/testsuite/g++.dg/parse/template15.C
new file mode 100644 (file)
index 0000000..ce2d130
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// Contributed by: Peter Schmid 
+//   <schmid at snake dot iap dot physik dot tu-darmstadt dot de>
+// PR c++/14545: constructor calls are not integer constant expressions
+
+struct A1 { A1(); }; 
+struct A2 { }; 
+
+template <class T> 
+struct B
+{ 
+  void foo() { 
+    A1();
+    A1 a1 = A1(); 
+
+    A2();
+    A2 a2 = A2(); 
+
+    int();
+    int a3 = int();
+    float();
+    float a4 = float();
+  } 
+}; 
+
+template struct B<void>;