This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCHes to fix -std=c++1z regressions


Now that I can easily run the testsuite in -std=c++1z mode, I can see various testsuite failures with that flag. This series of patches fixes those failures.

The first fixes various issues with 'auto' deduction: We were failing to diagnose various erroneous uses of auto, and crashing on the PR68597 testcase. Part of this patch moves the diagnosis of inconsistent deduction of auto out of do_auto_deduction and no longer uses the TREE_TYPE of the auto node at all.

The second fixes a few issues with handling of partial specialization with concepts.

The third fixes a few issues with C++1z generalized non-type template arguments.

The fourth fixes a crash on template/crash70.C, and also fixes more generally our handling of ::template where the template named is not a type, as in that testcase. There is no good reason to use the template keyword there, but it is well-formed.

The fifth fixes handling of decltype-call1.C; since concepts tries to tentatively parse a concept-introduction, we now first see the decltype in that tentative context, fail that tentative parse, and then parse it again later, but in the later context we've forgotten about the access checks that were involved. So this patch fixes CPP_DECLTYPE to carry the relevant access checks along with it, like CPP_TEMPLATE_ID.

The sixth fixes another issue related to tentative concept-introduction parsing, on parse/no-type-defn1.C: when we see "A<struct B{}*>" we call cp_parser_commit_to_tentative_parse when we see that we're parsing a class-head for B, even though it's an error. Here we can bring in my tentative parsing firewall trick again that I previously used for statement-expressions and lambdas: if we push a committed tentative parse level, cp_parser_commit_to_tentative_parse won't mess with levels past that one.

And the last patch updates some tests that were wrong for C++1z mode.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 15009525339d14188d38b60b079bef8362a389ed
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Dec 2 16:51:02 2015 -0500

    	PR c++/68597, fix auto9.C and auto-neg1.C with -std=c++1z.
    
    	* decl.c (check_tag_decl): Use ds_type_spec in auto diagnostic.
    	* typeck.c (check_return_expr): Check for inconsistent deduction.
    	* parser.c (class type_id_in_expr_sentinel): New.
    	(cp_parser_primary_expression) [RID_VA_ARG]: Use it.
    	(cp_parser_new_expression): Use it.
    	(cp_parser_trait_expr): Use it.
    	(cp_parser_type_id_1): Complain about auto if in_type_id_in_expr_p.
    	(cp_parser_default_type_template_argument): Check for auto.
    	(cp_parser_type_id_list): Likewise.
    	(cp_parser_simple_type_specifier): Allow auto parms if flag_concepts.
    	* pt.c (do_auto_deduction): Handle erroneous type.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e895c5a..0af7bd4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4555,8 +4555,9 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
     permerror (input_location, "declaration does not declare anything");
   else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
     {
-      error ("%<auto%> can only be specified for variables "
-	     "or function declarations");
+      error_at (declspecs->locations[ds_type_spec],
+		"%<auto%> can only be specified for variables "
+		"or function declarations");
       return error_mark_node;
     }
   /* Check for an anonymous union.  */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b28d17a9..85f6cc1 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -178,6 +178,22 @@ enum required_token {
   RT_TRANSACTION_CANCEL /* __transaction_cancel */
 };
 
+/* RAII wrapper for parser->in_type_id_in_expr_p, setting it on creation and
+   reverting it on destruction.  */
+
+class type_id_in_expr_sentinel
+{
+  cp_parser *parser;
+  bool saved;
+public:
+  type_id_in_expr_sentinel (cp_parser *parser, bool set = true)
+    : parser (parser),
+      saved (parser->in_type_id_in_expr_p)
+  { parser->in_type_id_in_expr_p = set; }
+  ~type_id_in_expr_sentinel ()
+  { parser->in_type_id_in_expr_p = saved; }
+};
+
 /* Prototypes.  */
 
 static cp_lexer *cp_lexer_new_main
@@ -4888,7 +4904,10 @@ cp_parser_primary_expression (cp_parser *parser,
 	    cp_parser_require (parser, CPP_COMMA, RT_COMMA);
 	    type_location = cp_lexer_peek_token (parser->lexer)->location;
 	    /* Parse the type-id.  */
-	    type = cp_parser_type_id (parser);
+	    {
+	      type_id_in_expr_sentinel s (parser);
+	      type = cp_parser_type_id (parser);
+	    }
 	    /* Look for the closing `)'.  */
 	    location_t finish_loc
 	      = cp_lexer_peek_token (parser->lexer)->location;
@@ -7907,7 +7926,10 @@ cp_parser_new_expression (cp_parser* parser)
       /* Parse the type-id.  */
       parser->type_definition_forbidden_message
 	= G_("types may not be defined in a new-expression");
-      type = cp_parser_type_id (parser);
+      {
+	type_id_in_expr_sentinel s (parser);
+	type = cp_parser_type_id (parser);
+      }
       parser->type_definition_forbidden_message = saved_message;
 
       /* Look for the closing `)'.  */
@@ -9391,7 +9413,10 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
 
   cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
-  type1 = cp_parser_type_id (parser);
+  {
+    type_id_in_expr_sentinel s (parser);
+    type1 = cp_parser_type_id (parser);
+  }
 
   if (type1 == error_mark_node)
     return error_mark_node;
@@ -9400,7 +9425,10 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     {
       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
  
-      type2 = cp_parser_type_id (parser);
+      {
+	type_id_in_expr_sentinel s (parser);
+	type2 = cp_parser_type_id (parser);
+      }
 
       if (type2 == error_mark_node)
 	return error_mark_node;
@@ -12149,6 +12177,11 @@ cp_parser_simple_declaration (cp_parser* parser,
       && !cp_parser_error_occurred (parser))
     cp_parser_commit_to_tentative_parse (parser);
 
+  tree last_type, auto_node;
+
+  last_type = NULL_TREE;
+  auto_node = type_uses_auto (decl_specifiers.type);
+
   /* Keep going until we hit the `;' at the end of the simple
      declaration.  */
   saw_declarator = false;
@@ -12190,6 +12223,24 @@ cp_parser_simple_declaration (cp_parser* parser,
 	 otherwise.)  */
       if (cp_parser_error_occurred (parser))
 	goto done;
+
+      if (auto_node)
+	{
+	  tree type = TREE_TYPE (decl);
+	  if (last_type && !same_type_p (type, last_type))
+	    {
+	      /* If the list of declarators contains more than one declarator,
+		 the type of each declared variable is determined as described
+		 above. If the type deduced for the template parameter U is not
+		 the same in each deduction, the program is ill-formed.  */
+	      error_at (decl_specifiers.locations[ds_type_spec],
+			"inconsistent deduction for %qT: %qT and then %qT",
+			decl_specifiers.type, last_type, type);
+	      auto_node = NULL_TREE;
+	    }
+	  last_type = type;
+	}
+
       /* Handle function definitions specially.  */
       if (function_definition_p)
 	{
@@ -14188,11 +14239,20 @@ cp_parser_default_type_template_argument (cp_parser *parser)
   /* Consume the `=' token.  */
   cp_lexer_consume_token (parser->lexer);
 
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
+
   /* Parse the default-argument.  */
   push_deferring_access_checks (dk_no_deferred);
   tree default_argument = cp_parser_type_id (parser);
   pop_deferring_access_checks ();
 
+  if (flag_concepts && type_uses_auto (default_argument))
+    {
+      error_at (token->location,
+		"invalid use of %<auto%> in default template argument");
+      return error_mark_node;
+    }
+
   return default_argument;
 }
 
@@ -15870,7 +15930,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 		     "use of %<auto%> in parameter declaration "
 		     "only available with "
 		     "-std=c++14 or -std=gnu++14");
-	  else
+	  else if (!flag_concepts)
 	    pedwarn (token->location, OPT_Wpedantic,
 		     "ISO C++ forbids use of %<auto%> in parameter "
 		     "declaration");
@@ -19647,7 +19707,7 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
 
   if (type_specifier_seq.type
       /* The concepts TS allows 'auto' as a type-id.  */
-      && !flag_concepts
+      && (!flag_concepts || parser->in_type_id_in_expr_p)
       /* None of the valid uses of 'auto' in C++14 involve the type-id
 	 nonterminal, but it is valid in a trailing-return-type.  */
       && !(cxx_dialect >= cxx14 && is_trailing_return)
@@ -22875,8 +22935,17 @@ cp_parser_type_id_list (cp_parser* parser)
       cp_token *token;
       tree type;
 
+      token = cp_lexer_peek_token (parser->lexer);
+
       /* Get the next type-id.  */
       type = cp_parser_type_id (parser);
+      /* Check for invalid 'auto'.  */
+      if (flag_concepts && type_uses_auto (type))
+	{
+	  error_at (token->location,
+		    "invalid use of %<auto%> in exception-specification");
+	  type = error_mark_node;
+	}
       /* Parse the optional ellipsis. */
       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
         {
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8435ddc..6e50fcd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23712,6 +23712,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
 	}
     }
 
+  if (type == error_mark_node)
+    return error_mark_node;
+
   init = resolve_nondeduced_context (init);
 
   if (AUTO_IS_DECLTYPE (auto_node))
@@ -23770,26 +23773,6 @@ do_auto_deduction (tree type, tree init, tree auto_node,
 	}
     }
 
-  /* If the list of declarators contains more than one declarator, the type
-     of each declared variable is determined as described above. If the
-     type deduced for the template parameter U is not the same in each
-     deduction, the program is ill-formed.  */
-  if (!flag_concepts && TREE_TYPE (auto_node)
-      && !same_type_p (TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0)))
-    {
-      if (cfun && auto_node == current_function_auto_return_pattern
-	  && LAMBDA_FUNCTION_P (current_function_decl))
-	error ("inconsistent types %qT and %qT deduced for "
-	       "lambda return type", TREE_TYPE (auto_node),
-	       TREE_VEC_ELT (targs, 0));
-      else
-	error ("inconsistent deduction for %qT: %qT and then %qT",
-	       auto_node, TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0));
-      return error_mark_node;
-    }
-  if (!flag_concepts)
-    TREE_TYPE (auto_node) = TREE_VEC_ELT (targs, 0);
-
   /* Check any placeholder constraints against the deduced type. */
   if (flag_concepts && !processing_template_decl)
     if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
@@ -23877,7 +23860,9 @@ is_auto_r (tree tp, void */*data*/)
 tree
 type_uses_auto (tree type)
 {
-  if (flag_concepts)
+  if (type == NULL_TREE)
+    return NULL_TREE;
+  else if (flag_concepts)
     {
       /* The Concepts TS allows multiple autos in one type-specifier; just
 	 return the first one we find, do_auto_deduction will collect all of
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0a1e446..3cf3c95 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8644,9 +8644,15 @@ check_return_expr (tree retval, bool *no_warning)
 	/* Leave it.  */;
       else if (functype == current_function_auto_return_pattern)
 	apply_deduced_return_type (current_function_decl, type);
-      else
-	/* A mismatch should have been diagnosed in do_auto_deduction.  */
-	gcc_assert (same_type_p (type, functype));
+      else if (!same_type_p (type, functype))
+	{
+	  if (LAMBDA_FUNCTION_P (current_function_decl))
+	    error ("inconsistent types %qT and %qT deduced for "
+		   "lambda return type", functype, type);
+	  else
+	    error ("inconsistent deduction for auto return type: "
+		   "%qT and then %qT", functype, type);
+	}
       functype = type;
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto9.C b/gcc/testsuite/g++.dg/cpp0x/auto9.C
index 83efbaa..ee20441 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto9.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto9.C
@@ -114,10 +114,10 @@ badthrow2 () throw (auto &)			// { dg-error "invalid use of|expected" }
 template <auto V = 4> struct G {};		// { dg-error "auto" }
 
 template <typename T> struct H { H (); ~H (); };
-H<auto> h;					// { dg-error "invalid" }
+H<auto> h;					// { dg-error "invalid|initializer" }
 
-void qq (auto);			// { dg-error "auto" }
-void qr (auto*);		// { dg-error "auto" }
+void qq (auto);		       // { dg-error "auto" "" { target { ! c++1z } } }
+void qr (auto*);	       // { dg-error "auto" "" { target { ! c++1z } } }
 
 // PR c++/46145
 typedef auto autot;		// { dg-error "auto" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult-neg.C b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult-neg.C
new file mode 100644
index 0000000..c45fe17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult-neg.C
@@ -0,0 +1,13 @@
+// PR c++/68597
+// { dg-do compile { target c++14 } }
+
+auto make_test_objective3(double beta) {
+  auto phi0_prime = [=](double alpha) {
+    if (alpha <= 1-beta)
+      return -1;
+    else if (alpha >= 1+beta)
+      return 1;
+    else
+      return 1 / beta * (alpha - 1); // { dg-error "type" }
+  };
+}
diff --git a/gcc/testsuite/g++.dg/other/anon-union3.C b/gcc/testsuite/g++.dg/other/anon-union3.C
index 94d0aec..3d99828 100644
--- a/gcc/testsuite/g++.dg/other/anon-union3.C
+++ b/gcc/testsuite/g++.dg/other/anon-union3.C
@@ -3,9 +3,9 @@
 class C
 {
   auto union      // { dg-error "storage class" "" { target { ! c++11 } } }
-    {
+    {		  // { dg-error "auto" "" { target c++11 } 5 }
       int a;
-    };            // { dg-error "multiple|specified" "" { target c++11 } }
+    };            // { dg-error "multiple types" "" { target c++11 } }
   register union  // { dg-error "storage class" }
     {
       int b;
commit 35e962aa724586088d54eb7c522529ef34ac04a9
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Dec 3 17:01:33 2015 -0500

    	Fix memclass5.C, memfriend10.C, var-templ19.C with -std=c++1z.
    
    	* constraint.cc (strictly_subsumes): New.
    	* cp-tree.h: Declare it.
    	* pt.c (process_partial_specialization): Use it instead of
    	subsumes_constraints.
    	(maybe_new_partial_specialization): Do compare null constraints.
    	* search.c (lookup_member): Handle currently_open_class returning null.

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 71e3e0d..89da6ec 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2314,6 +2314,15 @@ subsumes_constraints (tree a, tree b)
   return subsumes (a, b);
 }
 
+/* Returns true when the the constraints in A subsume those in B, but
+   the constraints in B do not subsume the constraints in A.  */
+
+bool
+strictly_subsumes (tree a, tree b)
+{
+  return subsumes (a, b) && !subsumes (b, a);
+}
+
 /* Determines which of the declarations, A or B, is more constrained.
    That is, which declaration's constraints subsume but are not subsumed
    by the other's?
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6ddab8a..1b2563d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6866,6 +6866,7 @@ extern bool constraints_satisfied_p             (tree, tree);
 extern bool equivalent_constraints              (tree, tree);
 extern bool equivalently_constrained            (tree, tree);
 extern bool subsumes_constraints                (tree, tree);
+extern bool strictly_subsumes			(tree, tree);
 extern int more_constrained                     (tree, tree);
 
 extern void diagnose_constraints                (location_t, tree, tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6e50fcd..22dcee2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -860,9 +860,11 @@ maybe_new_partial_specialization (tree type)
       tree type_constr = current_template_constraints ();
 
       if (type == TREE_TYPE (tmpl))
-	if (tree main_constr = get_constraints (tmpl))
+	{
+	  tree main_constr = get_constraints (tmpl);
 	  if (equivalent_constraints (type_constr, main_constr))
 	    return NULL_TREE;
+	}
 
       // Also, if there's a pre-existing specialization with matching
       // constraints, then this also isn't new.
@@ -4508,8 +4510,8 @@ process_partial_specialization (tree decl)
     = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (maintmpl)));
   if (comp_template_args (inner_args, INNERMOST_TEMPLATE_ARGS (main_args))
       && (!flag_concepts
-	  || !subsumes_constraints (current_template_constraints (),
-				    get_constraints (maintmpl))))
+	  || !strictly_subsumes (current_template_constraints (),
+				 get_constraints (maintmpl))))
     {
       if (!flag_concepts)
         error ("partial specialization %q+D does not specialize "
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 0c11a83..05a45c3 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1271,7 +1271,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,
   /* Make sure we're looking for a member of the current instantiation in the
      right partial specialization.  */
   if (flag_concepts && dependent_type_p (type))
-    type = currently_open_class (type);
+    if (tree t = currently_open_class (type))
+      type = t;
 
   if (!basetype_path)
     basetype_path = TYPE_BINFO (type);
commit 3780e53adaf5a66468e287eca62c4e91ac48a847
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Dec 4 16:06:24 2015 -0500

    	Fix template/ref1.C, nontype15.C, addr-builtin1.C with -std=c++1z.
    
    	* parser.c (cp_parser_template_argument): Handle references in
    	C++1z mode.
    	* constexpr.c (potential_constant_expression_1): Don't error about
    	TREE_THIS_VOLATILE on declarations.
    	[COMPONENT_REF]: Don't consider the object if we're dealing with an
    	overloaded function.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 42e9902..208f43b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4130,7 +4130,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     return false;
   if (t == NULL_TREE)
     return true;
-  if (TREE_THIS_VOLATILE (t))
+  if (TREE_THIS_VOLATILE (t) && !DECL_P (t))
     {
       if (flags & tf_error)
         error ("expression %qE has side-effects", t);
@@ -4345,6 +4345,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
             of literal type or of pointer to literal type.  */
       /* This test would be redundant, as it follows from the
 	 postfix-expression being a potential constant expression.  */
+      if (type_unknown_p (t))
+	return true;
       return RECUR (TREE_OPERAND (t, 0), want_rval);
 
     case EXPR_PACK_EXPANSION:
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 85f6cc1..1c7b1d5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15364,7 +15364,16 @@ cp_parser_template_argument (cp_parser* parser)
      because the argument could really be a type-id.  */
   if (maybe_type_id)
     cp_parser_parse_tentatively (parser);
-  argument = cp_parser_constant_expression (parser);
+
+  if (cxx_dialect <= cxx14)
+    argument = cp_parser_constant_expression (parser);
+  else
+    {
+      /* With C++17 generalized non-type template arguments we need to handle
+	 lvalue constant expressions, too.  */
+      argument = cp_parser_assignment_expression (parser);
+      require_potential_constant_expression (argument);
+    }
 
   if (!maybe_type_id)
     return argument;
diff --git a/gcc/testsuite/g++.dg/template/nontype8.C b/gcc/testsuite/g++.dg/template/nontype8.C
index d2976df..d31f892 100644
--- a/gcc/testsuite/g++.dg/template/nontype8.C
+++ b/gcc/testsuite/g++.dg/template/nontype8.C
@@ -8,6 +8,6 @@ struct S { int m; static int s; } s;
 
 X<&a[2]> x3;                    // { dg-error "" } address of array element
 X<&s.m> x4;                     // { dg-error "" } address of non-static member
-X<&s.s> x5;                     // { dg-error "" } &S::s must be used
+X<&s.s> x5;                     // { dg-error "" "" { target { ! c++1z } } } &S::s must be used
 X<&S::s> x6;                    // OK: address of static member
 
commit 30ab8419405883335477c0dd4b0addea0285727f
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Dec 4 17:59:01 2015 -0500

    	Fix crash70.C with -std=c++1z.
    
    	* semantics.c (finish_qualified_id_expr): Handle
    	UNBOUND_CLASS_TEMPLATE.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 82f7d3a..80d1b10 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1929,7 +1929,17 @@ finish_qualified_id_expr (tree qualifying_class,
     return error_mark_node;
 
   if (template_p)
-    check_template_keyword (expr);
+    {
+      if (TREE_CODE (expr) == UNBOUND_CLASS_TEMPLATE)
+	/* cp_parser_lookup_name thought we were looking for a type,
+	   but we're actually looking for a declaration.  */
+	expr = build_qualified_name (/*type*/NULL_TREE,
+				     TYPE_CONTEXT (expr),
+				     TYPE_IDENTIFIER (expr),
+				     /*template_p*/true);
+      else
+	check_template_keyword (expr);
+    }
 
   /* If EXPR occurs as the operand of '&', use special handling that
      permits a pointer-to-member.  */
diff --git a/gcc/testsuite/g++.dg/template/crash70.C b/gcc/testsuite/g++.dg/template/crash70.C
index 742f77b..9ccadfb 100644
--- a/gcc/testsuite/g++.dg/template/crash70.C
+++ b/gcc/testsuite/g++.dg/template/crash70.C
@@ -2,6 +2,6 @@
 
 template<int> struct A;
 
-template<typename T> void foo (A<&T::template i>); // { dg-error "not a template" }
+template<typename T> void foo (A<&T::template i>);
 
 template void foo<A<0> > (A<0>); // { dg-error "does not match" }
commit 1d6d95fb4546f33dbba343a72c6e643314683955
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Dec 5 15:23:35 2015 -0500

    	Fix decltype-call1.C with -std=c++1z.
    
    	* parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses
    	tree_check_value.
    	* parser.c (cp_parser_decltype): Use tree_check_value.
    	(saved_checks_value): New.
    	(cp_parser_nested_name_specifier_opt): Use it.
    	(cp_parser_template_id): Use it.
    	(cp_parser_simple_type_specifier): Use it.
    	(cp_parser_pre_parsed_nested_name_specifier): Use it.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1c7b1d5..ce5a21a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1008,6 +1008,28 @@ cp_lexer_next_token_is_decltype (cp_lexer *lexer)
   return token_is_decltype (t);
 }
 
+/* Called when processing a token with tree_check_value; perform or defer the
+   associated checks and return the value.  */
+
+static tree
+saved_checks_value (struct tree_check *check_value)
+{
+  /* Perform any access checks that were deferred.  */
+  vec<deferred_access_check, va_gc> *checks;
+  deferred_access_check *chk;
+  checks = check_value->checks;
+  if (checks)
+    {
+      int i;
+      FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+	perform_or_defer_access_check (chk->binfo,
+				       chk->decl,
+				       chk->diag_decl, tf_warning_or_error);
+    }
+  /* Return the stored value.  */
+  return check_value->value;
+}
+
 /* Return a pointer to the Nth token in the token stream.  If N is 1,
    then this is precisely equivalent to cp_lexer_peek_token (except
    that it is not inline).  One would like to disallow that case, but
@@ -5818,7 +5840,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
 	      token = cp_lexer_consume_token (parser->lexer);
 	      error_at (token->location, "decltype evaluates to %qT, "
 			"which is not a class or enumeration type",
-			token->u.value);
+			token->u.tree_check_value->value);
 	      parser->scope = error_mark_node;
 	      error_p = true;
 	      /* As below.  */
@@ -13016,7 +13038,7 @@ cp_parser_decltype (cp_parser *parser)
     {
       /* Already parsed.  */
       cp_lexer_consume_token (parser->lexer);
-      return start_token->u.value;
+      return saved_checks_value (start_token->u.tree_check_value);
     }
 
   /* Look for the `decltype' token.  */
@@ -13101,7 +13123,9 @@ cp_parser_decltype (cp_parser *parser)
   /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
      it again.  */
   start_token->type = CPP_DECLTYPE;
-  start_token->u.value = expr;
+  start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
+  start_token->u.tree_check_value->value = expr;
+  start_token->u.tree_check_value->checks = get_deferred_access_checks ();
   start_token->keyword = RID_MAX;
   cp_lexer_purge_tokens_after (parser->lexer, start_token);
 
@@ -14617,13 +14641,10 @@ cp_parser_template_id (cp_parser *parser,
 		       enum tag_types tag_type,
 		       bool is_declaration)
 {
-  int i;
   tree templ;
   tree arguments;
   tree template_id;
   cp_token_position start_of_id = 0;
-  deferred_access_check *chk;
-  vec<deferred_access_check, va_gc> *access_check;
   cp_token *next_token = NULL, *next_token_2 = NULL;
   bool is_identifier;
 
@@ -14632,22 +14653,8 @@ cp_parser_template_id (cp_parser *parser,
   next_token = cp_lexer_peek_token (parser->lexer);
   if (next_token->type == CPP_TEMPLATE_ID)
     {
-      struct tree_check *check_value;
-
-      /* Get the stored value.  */
-      check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
-      /* Perform any access checks that were deferred.  */
-      access_check = check_value->checks;
-      if (access_check)
-	{
-	  FOR_EACH_VEC_ELT (*access_check, i, chk)
-	    perform_or_defer_access_check (chk->binfo,
-					   chk->decl,
-					   chk->diag_decl,
-					   tf_warning_or_error);
-	}
-      /* Return the stored value.  */
-      return check_value->value;
+      cp_lexer_consume_token (parser->lexer);
+      return saved_checks_value (next_token->u.tree_check_value);
     }
 
   /* Avoid performing name lookup if there is no possibility of
@@ -15999,7 +16006,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   if (token->type == CPP_DECLTYPE
       && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
     {
-      type = token->u.value;
+      type = saved_checks_value (token->u.tree_check_value);
       if (decl_specs)
 	{
 	  cp_parser_set_decl_spec_type (decl_specs, type,
@@ -27042,24 +27049,12 @@ cp_parser_optional_template_keyword (cp_parser *parser)
 static void
 cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
 {
-  int i;
   struct tree_check *check_value;
-  deferred_access_check *chk;
-  vec<deferred_access_check, va_gc> *checks;
 
   /* Get the stored value.  */
   check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
-  /* Perform any access checks that were deferred.  */
-  checks = check_value->checks;
-  if (checks)
-    {
-      FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
-	perform_or_defer_access_check (chk->binfo,
-				       chk->decl,
-				       chk->diag_decl, tf_warning_or_error);
-    }
   /* Set the scope from the stored value.  */
-  parser->scope = check_value->value;
+  parser->scope = saved_checks_value (check_value);
   parser->qualifying_scope = check_value->qualifying_scope;
   parser->object_scope = NULL_TREE;
 }
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index a6b8e74..891dd41 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -63,11 +63,13 @@ struct GTY (()) cp_token {
   location_t location;
   /* The value associated with this token, if any.  */
   union cp_token_value {
-    /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID.  */
+    /* Used for compound tokens such as CPP_NESTED_NAME_SPECIFIER.  */
     struct tree_check* GTY((tag ("1"))) tree_check_value;
     /* Use for all other tokens.  */
     tree GTY((tag ("0"))) value;
-  } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
+  } GTY((desc ("(%1.type == CPP_TEMPLATE_ID)"
+	       "|| (%1.type == CPP_NESTED_NAME_SPECIFIER)"
+	       "|| (%1.type == CPP_DECLTYPE)"))) u;
 };
 
 
commit 54b5f344b3603c942a9159c2a067a4c75f413080
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Dec 5 23:09:25 2015 -0500

    	Fix parse/no-type-defn1.C with -std=c++1z.
    
    	* parser.c (struct tentative_firewall): New.
    	(cp_parser_template_id, cp_parser_decltype_expr): Use it.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ce5a21a..3e90f11 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4326,6 +4326,43 @@ cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start,
   cp_lexer_purge_tokens_after (parser->lexer, start);
 }
 
+/* Like the above functions, but let the user modify the tokens.  Used by
+   CPP_DECLTYPE and CPP_TEMPLATE_ID, where we are saving the side-effects for
+   later parses, so it makes sense to localize the effects of
+   cp_parser_commit_to_tentative_parse.  */
+
+struct tentative_firewall
+{
+  cp_parser *parser;
+  bool set;
+
+  tentative_firewall (cp_parser *p): parser(p)
+  {
+    /* If we're currently parsing tentatively, start a committed level as a
+       firewall and then an inner tentative parse.  */
+    if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser)))
+      {
+	cp_parser_parse_tentatively (parser);
+	cp_parser_commit_to_topmost_tentative_parse (parser);
+	cp_parser_parse_tentatively (parser);
+      }
+  }
+
+  ~tentative_firewall()
+  {
+    if (set)
+      {
+	/* Finish the inner tentative parse and the firewall, propagating any
+	   uncommitted error state to the outer tentative parse.  */
+	bool err = cp_parser_error_occurred (parser);
+	cp_parser_parse_definitely (parser);
+	cp_parser_parse_definitely (parser);
+	if (err)
+	  cp_parser_simulate_error (parser);
+      }
+  }
+};
+
 /* Parse a GNU statement-expression, i.e. ({ stmts }), except for the
    enclosing parentheses.  */
 
@@ -12921,6 +12958,11 @@ cp_parser_decltype_expr (cp_parser *parser,
   cp_token *id_expr_start_token;
   tree expr;
 
+  /* Since we're going to preserve any side-effects from this parse, set up a
+     firewall to protect our callers from cp_parser_commit_to_tentative_parse
+     in the expression.  */
+  tentative_firewall firewall (parser);
+
   /* First, try parsing an id-expression.  */
   id_expr_start_token = cp_lexer_peek_token (parser->lexer);
   cp_parser_parse_tentatively (parser);
@@ -14687,6 +14729,11 @@ cp_parser_template_id (cp_parser *parser,
       return templ;
     }
 
+  /* Since we're going to preserve any side-effects from this parse, set up a
+     firewall to protect our callers from cp_parser_commit_to_tentative_parse
+     in the template arguments.  */
+  tentative_firewall firewall (parser);
+
   /* If we find the sequence `[:' after a template-name, it's probably
      a digraph-typo for `< ::'. Substitute the tokens and check if we can
      parse correctly the argument list.  */
diff --git a/gcc/testsuite/g++.dg/parse/no-type-defn1.C b/gcc/testsuite/g++.dg/parse/no-type-defn1.C
index 9e89957..a8d6ad8 100644
--- a/gcc/testsuite/g++.dg/parse/no-type-defn1.C
+++ b/gcc/testsuite/g++.dg/parse/no-type-defn1.C
@@ -3,3 +3,5 @@
 template<typename> struct A { };
 A< struct B { }* >::SomeNonSense // { dg-error "types may not be defined" }
 int y;
+
+// { dg-prune-output "SomeNonSense" }
commit 4f11915675f0488e85518178da8f646756b13664
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Dec 3 17:11:38 2015 -0500

    	* g++.dg/cpp0x/static_assert8.C: Fix for -std=c++1z.
    	* g++.dg/cpp0x/auto3.C: Fix for -std=c++1z.
    	* g++.dg/cpp1y/feat-cxx14.C: Only run with -std=c++14.
    	* g++.dg/cpp1y/feat-cxx14-neg.C: Only run with -std=c++14.
    	* g++.dg/cpp1z/feat-cxx1z.C: Fill in from feat-cxx14.C.
    	* g++.dg/cpp1z/fold5.C: Don't run with -std=c++1z.
    	* g++.dg/template/function1.C: Don't run with -std=c++1z.
    	* g++.dg/template/call4.C: Fix access.
    	* g++.dg/parse/crash31.C: Remove expected error text.

diff --git a/gcc/testsuite/g++.dg/cpp0x/auto3.C b/gcc/testsuite/g++.dg/cpp0x/auto3.C
index 5bfed1b..27aab57 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
@@ -17,11 +17,11 @@ struct A { };
 
 A<int> A1;
 // CWG issue 625
-A<auto> A2 = A1;		// { dg-error "" }
+A<auto> A2 = A1;		// { dg-error "" "" { target { ! c++1z } } }
 
 auto foo() { }			// { dg-error "auto" "" { target { ! c++14 } } }
 
-void bar(auto i)		// { dg-error "incomplete|auto" }
+void bar(auto i)		// { dg-error "incomplete|auto" "" { target { ! c++1z } } }
 {
   (void)i;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert8.C b/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
index 972f859..6602e70 100644
--- a/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
+++ b/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
@@ -6,4 +6,4 @@ static_assert (1 == 0,); // { dg-error "expected string-literal before '\\)'" }
 
 static_assert (1 == 0, "oops"); // { dg-error "static assertion failed" }
 
-// { dg-error "static_assert without a message only available with " "" { target *-*-* } 3 }
+// { dg-error "static_assert without a message only available with " "" { target { ! c++1z } } 3 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
index 221bd3f..d5793ab 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
@@ -1,4 +1,4 @@
-// { dg-do compile { target c++14 } }
+// { dg-options -std=c++14 }
 
 // C++17 features:
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C
index 1292966..d9dbf62 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14.C
@@ -1,5 +1,4 @@
-// { dg-do compile { target c++14 } }
-// { dg-options "-I${srcdir}/g++.dg/cpp1y -I${srcdir}/g++.dg/cpp1y/testinc" }
+// { dg-options "-std=c++14 -I${srcdir}/g++.dg/cpp1y -I${srcdir}/g++.dg/cpp1y/testinc" }
 
 //  C++98 features:
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
index ead1665..9b3b284 100644
--- a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
+++ b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
@@ -1,5 +1,306 @@
-// { dg-do compile }
-// { dg-options "-std=c++1z" }
+// { dg-options "-std=c++1z -I${srcdir}/g++.dg/cpp1y -I${srcdir}/g++.dg/cpp1y/testinc" }
+
+//  C++98 features:
+
+#ifndef __cpp_rtti
+#  error "__cpp_rtti"
+#elif  __cpp_rtti != 199711
+#  error "__cpp_rtti != 199711"
+#endif
+
+#ifndef __cpp_exceptions
+#  error "__cpp_exceptions"
+#elif  __cpp_exceptions != 199711
+#  error "__cpp_exceptions != 199711"
+#endif
+
+//  C++11 features:
+
+#ifndef __cpp_raw_strings
+#  error "__cpp_raw_strings"
+#elif __cpp_raw_strings != 200710
+#  error "__cpp_raw_strings != 200710"
+#endif
+
+#ifndef __cpp_unicode_literals
+#  error "__cpp_unicode_literals"
+#elif __cpp_unicode_literals != 200710
+#  error "__cpp_unicode_literals != 200710"
+#endif
+
+#ifndef __cpp_user_defined_literals
+#  error "__cpp_user_defined_literals"
+#elif __cpp_user_defined_literals != 200809
+#  error "__cpp_user_defined_literals != 200809"
+#endif
+
+#ifndef __cpp_lambdas
+#  error "__cpp_lambdas"
+#elif __cpp_lambdas != 200907
+#  error "__cpp_lambdas != 200907"
+#endif
+
+#ifndef __cpp_range_based_for
+#  error "__cpp_range_based_for"
+#elif __cpp_range_based_for != 200907
+#  error "__cpp_range_based_for != 200907"
+#endif
+
+#ifndef __cpp_decltype
+#  error "__cpp_decltype"
+#elif __cpp_decltype != 200707
+#  error "__cpp_decltype != 200707"
+#endif
+
+#ifndef __cpp_attributes
+#  error "__cpp_attributes"
+#elif __cpp_attributes != 200809
+#  error "__cpp_attributes != 200809"
+#endif
+
+#ifndef __cpp_rvalue_reference
+#  error "__cpp_rvalue_reference"
+#elif __cpp_rvalue_reference != 200610
+#  error "__cpp_rvalue_reference != 200610"
+#endif
+
+#ifndef __cpp_variadic_templates
+#  error "__cpp_variadic_templates"
+#elif __cpp_variadic_templates != 200704
+#  error "__cpp_variadic_templates != 200704"
+#endif
+
+#ifndef __cpp_initializer_lists
+#  error "__cpp_initializer_lists"
+#elif __cpp_initializer_lists != 200806
+#  error "__cpp_initializer_lists != 200806"
+#endif
+
+#ifndef __cpp_delegating_constructors
+#  error "__cpp_delegating_constructors"
+#elif __cpp_delegating_constructors != 200604
+#  error "__cpp_delegating_constructors != 200604"
+#endif
+
+#ifndef __cpp_nsdmi
+#  error "__cpp_nsdmi"
+#elif __cpp_nsdmi != 200809
+#  error "__cpp_nsdmi != 200809"
+#endif
+
+#ifndef __cpp_inheriting_constructors
+#  error "__cpp_inheriting_constructors"
+#elif  __cpp_inheriting_constructors!= 200802
+#  error "__cpp_inheriting_constructors != 200802"
+#endif
+
+#ifndef __cpp_ref_qualifiers
+#  error "__cpp_ref_qualifiers"
+#elif __cpp_ref_qualifiers != 200710
+#  error "__cpp_ref_qualifiers != 200710"
+#endif
+
+#ifndef __cpp_alias_templates
+#  error "__cpp_alias_templates"
+#elif __cpp_alias_templates != 200704
+#  error "__cpp_alias_templates != 200704"
+#endif
+
+//  C++14 features:
+
+#ifndef __cpp_binary_literals
+#  error "__cpp_binary_literals"
+#elif __cpp_binary_literals != 201304
+#  error "__cpp_binary_literals != 201304"
+#endif
+
+#ifndef __cpp_init_captures
+#  error "__cpp_init_captures"
+#elif __cpp_init_captures != 201304
+#  error "__cpp_init_captures != 201304"
+#endif
+
+#ifndef __cpp_generic_lambdas
+#  error "__cpp_generic_lambdas"
+#elif __cpp_generic_lambdas != 201304
+#  error "__cpp_generic_lambdas != 201304"
+#endif
+
+#ifndef __cpp_constexpr
+#  error "__cpp_constexpr"
+#elif __cpp_constexpr != 201304
+#  error "__cpp_constexpr != 201304"
+#endif
+
+#ifndef __cpp_decltype_auto
+#  error "__cpp_decltype_auto"
+#elif __cpp_decltype_auto != 201304
+#  error "__cpp_decltype_auto != 201304"
+#endif
+
+#ifndef __cpp_return_type_deduction
+#  error "__cpp_return_type_deduction"
+#elif __cpp_return_type_deduction != 201304
+#  error "__cpp_return_type_deduction != 201304"
+#endif
+
+#ifndef __cpp_aggregate_nsdmi
+#  error "__cpp_aggregate_nsdmi"
+#elif __cpp_aggregate_nsdmi != 201304
+#  error "__cpp_aggregate_nsdmi != 201304"
+#endif
+
+#ifndef __cpp_variable_templates
+#  error "__cpp_variable_templates"
+#elif __cpp_variable_templates != 201304
+#  error "__cpp_variable_templates != 201304"
+#endif
+
+#ifndef __cpp_digit_separators
+#  error "__cpp_digit_separators"
+#elif __cpp_digit_separators != 201309
+#  error "__cpp_digit_separators != 201309"
+#endif
+
+#ifndef __cpp_sized_deallocation
+#  error "__cpp_sized_deallocation"
+#elif __cpp_sized_deallocation != 201309
+#  error "__cpp_sized_deallocation != 201309"
+#endif
+
+//  GNU VLA support:
+
+#ifndef __cpp_runtime_arrays
+#  error "__cpp_runtime_arrays"
+#elif __cpp_runtime_arrays != 198712
+#  error "__cpp_runtime_arrays != 198712"
+#endif
+
+//  C++11 attributes:
+
+#ifdef __has_cpp_attribute
+#  if ! __has_cpp_attribute(noreturn)
+#    error "__has_cpp_attribute(noreturn)"
+#  elif __has_cpp_attribute(noreturn) != 200809
+#    error "__has_cpp_attribute(noreturn) != 200809"
+#  endif
+#else
+#  error "__has_cpp_attribute"
+#endif
+
+//  Attribute carries_dependency not in yet.
+//#ifdef __has_cpp_attribute
+//#  if ! __has_cpp_attribute(carries_dependency)
+//#    error "__has_cpp_attribute(carries_dependency)"
+//#  elif __has_cpp_attribute(carries_dependency) != 200809
+//#    error "__has_cpp_attribute(carries_dependency) != 200809"
+//#  endif
+//#else
+//#  error "__has_cpp_attribute"
+//#endif
+
+//  C++14 attributes:
+
+#ifdef __has_cpp_attribute
+#  if ! __has_cpp_attribute(deprecated)
+#    error "__has_cpp_attribute(deprecated)"
+#  elif __has_cpp_attribute(deprecated) != 201309
+#    error "__has_cpp_attribute(deprecated) != 201309"
+#  endif
+#else
+#  error "__has_cpp_attribute"
+#endif
+
+//  Include checks:
+
+//  Check for __has_include macro.
+#ifndef __has_include
+#  error "__has_include"
+#endif
+
+//  Quoted complex.h should find at least the bracket version (use operator).
+#if __has_include__ "complex.h"
+#else
+#  error "complex.h"
+#endif
+
+//  Try known bracket header (use operator).
+#if __has_include__(<complex>)
+#else
+#  error "<complex>"
+#endif
+
+//  Define and use a macro to invoke the operator.
+#define sluggo(TXT) __has_include__(TXT)
+
+#if sluggo(<complex>)
+#else
+#  error "<complex>"
+#endif
+
+#if ! sluggo(<complex>)
+#  error "<complex>"
+#else
+#endif
+
+//  Quoted complex.h should find at least the bracket version.
+#if __has_include("complex.h")
+#else
+#  error "complex.h"
+#endif
+
+//  Try known local quote header.
+#if __has_include("complex_literals.h")
+#else
+#  error "\"complex_literals.h\""
+#endif
+
+//  Try nonexistent bracket header.
+#if __has_include(<stuff>)
+#  error "<stuff>"
+#else
+#endif
+
+//  Try nonexistent quote header.
+#if __has_include("phlegm")
+#  error "\"phlegm\""
+#else
+#endif
+
+//  Test __has_include_next.
+#if __has_include("phoobhar.h")
+#  include "phoobhar.h"
+#else
+#  error "__has_include(\"phoobhar.h\")"
+#endif
+
+//  Try a macro.
+#define COMPLEX_INC "complex.h"
+#if __has_include(COMPLEX_INC)
+#else
+#  error COMPLEX_INC
+#endif
+
+//  Realistic use of __has_include.
+#if __has_include(<array>)
+#  define STD_ARRAY 1
+#  include <array>
+  template<typename _Tp, size_t _Num>
+    using array = std::array<_Tp, _Num>;
+#elif __has_include(<tr1/array>)
+#  define TR1_ARRAY 1
+#  include <tr1/array>
+  template<typename _Tp, size_t _Num>
+    typedef std::tr1::array<_Tp, _Num> array;
+#endif
+
+// C++17 features:
+
+#ifndef __cpp_unicode_characters
+#  error "__cpp_unicode_characters"
+#elif __cpp_unicode_characters != 201411
+#  error "__cpp_unicode_characters != 201411"
+#endif
 
 #ifndef __cpp_static_assert
 #  error "__cpp_static_assert"
@@ -13,8 +314,26 @@
 #  error "__cpp_namespace_attributes != 201411"
 #endif
 
+#ifndef __cpp_enumerator_attributes
+#  error "__cpp_enumerator_attributes"
+#elif __cpp_enumerator_attributes != 201411
+#  error "__cpp_enumerator_attributes != 201411"
+#endif
+
 #ifndef __cpp_nested_namespace_definitions
 #  error "__cpp_nested_namespace_definitions"
 #elif __cpp_nested_namespace_definitions != 201411
 #  error "__cpp_nested_namespace_definitions != 201411"
 #endif
+
+#ifndef __cpp_fold_expressions
+#  error "__cpp_fold_expressions"
+#elif __cpp_fold_expressions != 201411
+#  error "__cpp_fold_expressions != 201411"
+#endif
+
+#ifndef __cpp_nontype_template_args
+#  error "__cpp_nontype_template_args"
+#elif __cpp_nontype_template_args != 201411
+#  error "__cpp_nontype_template_args != 201411"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp1z/fold5.C b/gcc/testsuite/g++.dg/cpp1z/fold5.C
index 0721419..da6544b 100644
--- a/gcc/testsuite/g++.dg/cpp1z/fold5.C
+++ b/gcc/testsuite/g++.dg/cpp1z/fold5.C
@@ -1,5 +1,5 @@
 // Test that we complain about fold-expressions in C++11 and C++14.
-// { dg-do compile { target c++11 } }
+// { dg-do compile { target { c++11 && { ! c++1z } } } }
 
 template <class...T>
 constexpr int f(T... t)
diff --git a/gcc/testsuite/g++.dg/parse/crash31.C b/gcc/testsuite/g++.dg/parse/crash31.C
index e7d6bdc..b7ca1e4 100644
--- a/gcc/testsuite/g++.dg/parse/crash31.C
+++ b/gcc/testsuite/g++.dg/parse/crash31.C
@@ -1,9 +1,9 @@
-struct A // { dg-message "not complete" }
+struct A
 {
-  A : A; // { dg-error "expected|incomplete" }
-  A : B; // { dg-error "not declared|incomplete" }
-  A : A(); // { dg-error "undefined type|incomplete" }
-  A : B(); // { dg-error "function call|incomplete|not declared" }
-  A : A[]; // { dg-error "expected|array reference|incomplete" }
-  A : B[]; // { dg-error "not declared|expected|array reference|incomplete" }
+  A : A; // { dg-error "" }
+  A : B; // { dg-error "" }
+  A : A(); // { dg-error "" }
+  A : B(); // { dg-error "" }
+  A : A[]; // { dg-error "" }
+  A : B[]; // { dg-error "" }
 };
diff --git a/gcc/testsuite/g++.dg/template/call4.C b/gcc/testsuite/g++.dg/template/call4.C
index 1f7eb4c..1958769 100644
--- a/gcc/testsuite/g++.dg/template/call4.C
+++ b/gcc/testsuite/g++.dg/template/call4.C
@@ -1,6 +1,6 @@
 // PR c++/25364
 
-class OFX_PropertySuiteV1
+struct OFX_PropertySuiteV1
 {
   static int propGetDouble ();
 };
diff --git a/gcc/testsuite/g++.dg/template/function1.C b/gcc/testsuite/g++.dg/template/function1.C
index bceed9d..f234585 100644
--- a/gcc/testsuite/g++.dg/template/function1.C
+++ b/gcc/testsuite/g++.dg/template/function1.C
@@ -1,5 +1,5 @@
 // PR c++/38647
-// { dg-do compile }
+// { dg-do compile { target { ! c++1z } } }
 // { dg-prune-output "note" }
 
 template<const char *, int> struct A {};

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]