semantics.c (constexpr_fn_retval): Ignore declarations in C++14.
authorJason Merrill <jason@redhat.com>
Fri, 3 Oct 2014 16:48:18 +0000 (12:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 3 Oct 2014 16:48:18 +0000 (12:48 -0400)
* semantics.c (constexpr_fn_retval): Ignore declarations in C++14.
(var_in_constexpr_fn): New.
(cxx_eval_constant_expression): Look into DECL_INITIAL.
(potential_constant_expression_1): Allow constexpr-local vars.

From-SVN: r215862

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C [new file with mode: 0644]

index 4f91a68824bf1748d8c92650ff864086a74737e3..56c3bdbd51b9fa2f9597412f68a5faa25622f487 100644 (file)
@@ -1,5 +1,10 @@
 2014-10-03  Jason Merrill  <jason@redhat.com>
 
+       * semantics.c (constexpr_fn_retval): Ignore declarations in C++14.
+       (var_in_constexpr_fn): New.
+       (cxx_eval_constant_expression): Look into DECL_INITIAL.
+       (potential_constant_expression_1): Allow constexpr-local vars.
+
        PR c++/63362
        * tree.c (strip_typedefs): Handle TREE_LIST.
 
index fe1651ef010dc2eeab36ff8f4eda4b60fd284882..857af769f2b0b2521743eee3f45ab9fa5aba8c82 100644 (file)
@@ -5833,6 +5833,7 @@ extern tree maybe_constant_value (tree);
 extern tree maybe_constant_init (tree);
 extern bool is_sub_constant_expr (tree);
 extern bool reduced_constant_expression_p (tree);
+extern bool var_in_constexpr_fn (tree);
 extern void explain_invalid_constexpr_fn (tree);
 extern vec<tree> cx_error_context (void);
 extern bool is_this_parameter (tree);
index 756982667b1b02abbfa9016b4647be904dd70abb..6c6a5c8821422f0de2165555571f567be3181f7a 100644 (file)
@@ -8018,6 +8018,8 @@ constexpr_fn_retval (tree body)
     case DECL_EXPR:
       if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL)
        return NULL_TREE;
+      if (cxx_dialect >= cxx14)
+       return NULL_TREE;
       return error_mark_node;
 
     case CLEANUP_POINT_EXPR:
@@ -9596,6 +9598,14 @@ cxx_eval_trinary_expression (const constexpr_call *call, tree t,
   return val;
 }
 
+bool
+var_in_constexpr_fn (tree t)
+{
+  tree ctx = DECL_CONTEXT (t);
+  return (cxx_dialect >= cxx14 && ctx && TREE_CODE (ctx) == FUNCTION_DECL
+         && DECL_DECLARED_CONSTEXPR_P (ctx));
+}
+
 /* Attempt to reduce the expression T to a constant value.
    On failure, issue diagnostic and return error_mark_node.  */
 /* FIXME unify with c_fully_fold */
@@ -9635,6 +9645,11 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
       if (TREE_CODE (r) == TARGET_EXPR
          && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
        r = TARGET_EXPR_INITIAL (r);
+      if (DECL_P (r) && var_in_constexpr_fn (r)
+         && DECL_INITIAL (r))
+       r = cxx_eval_constant_expression (call, DECL_INITIAL (r),
+                                         allow_non_constant, false,
+                                         non_constant_p, overflow_p);
       if (DECL_P (r))
        {
          if (!allow_non_constant)
@@ -10320,6 +10335,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
 
     case VAR_DECL:
       if (want_rval && !decl_constant_var_p (t)
+         && !var_in_constexpr_fn (t)
          && !dependent_type_p (TREE_TYPE (t)))
         {
           if (flags & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C
new file mode 100644 (file)
index 0000000..39c3ee8
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++14 } }
+
+constexpr int f(int i) { int j = i+1; return j; }
+
+constexpr int i = f(41);
+
+#define SA(X) static_assert((X),#X)
+
+SA(i==42);