summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2018-03-10 05:45:21 -0300
committerAlexandre Oliva <aoliva@redhat.com>2018-03-10 07:32:35 -0300
commit54b21b6b6c25f8fd81efc7b5b1dbd8e1a2dde120 (patch)
treed355ea1b4a2a68d62b8ecef8c8ad16895b24da52
parent62ad1c4d0355bed8ccfac65460cc3267b5686a28 (diff)
downloadgcc-54b21b6b6c25f8fd81efc7b5b1dbd8e1a2dde120.tar.gz
[PR c++/84647] undeclared fn called in auto default arg in ptr decl
We ICEd when attempting to convert a default arg for an auto parm, the default arg amounting to a call to an undeclared function, in a declaration of a pointer to function variable. It's all wrong, but because of the bogus implicit template, we accept the typeless expression at first. Later on, after we finish the implicit template because it's bogus (but deferring the reporting of the error to the end of cp_parser_init_declarator), no longer processing_template_decl, we attempt to perform the impossible conversion from NULL type to an unresolved and unresolvable type placeholder. We crash in implicit_conversion because FROM is NULL, and then (once we arrange to return a NULL conversion there) in perform_implicit_conversion_flags when trying to determine whether the expr is an invalid use of a nonstatic memfn. This patch makes implicit_conversion return NULL when the FROM type is NULL, and reports a proper error for typeless EXPRs in perform_implicit_conversion_flags. I considered testing for !processing_template_decl, but decided not to bother. FWIW, I'd tried temporarily incrementing processing_template_decl while completing the parsing of the bogus implicit template, but that didn't go very well: we'd skip the conversion all right, but start_decl would attempt to push_template_decl, and that would silently return error_mark_node, which would in turn silence the bogus implicit template error. With -fpermissive, all the other errors (misplaced auto, unexpected default arg in pointer declaration, and undeclared function call) would be turned to warnings or vanish altogether, so compilation would complete in spite of the bogus parsing and the failed template declaration. I decided not to explore that path further, and ended up working around the errors in the conversion, so as to make sure we'd get at least some error (we get all of them with the enclosed testcase). for gcc/cp/ChangeLog PR c++/84647 * call.c (implicit_conversion): Return NULL conv for NULL from type. (perform_implicit_conversion_flags): If conv is NULL, check for NULL expr type and report an error instead of ICEing. for gcc/testsuite/ChangeLog PR c++/84647 * g++.dg/cpp0x/pr84647.C: New.
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr84647.C3
2 files changed, 13 insertions, 0 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f83d51f3457..5ce433007d3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1834,6 +1834,9 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
from = TREE_TYPE (expr);
}
+ if (!from)
+ return NULL;
+
if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
else
@@ -10572,6 +10575,13 @@ perform_implicit_conversion_flags (tree type, tree expr,
Call instantiate_type to get good error messages. */
if (TREE_TYPE (expr) == unknown_type_node)
instantiate_type (type, expr, complain);
+ /* We may find this if we parse a default argument as part
+ of a bogus implicit template function declaration. It
+ might be a template-dependent expression, or a call of an
+ undeclared function. */
+ else if (!TREE_TYPE (expr))
+ error_at (loc, "cannot convert typeless expression %qE",
+ expr);
else if (invalid_nonstatic_memfn_p (loc, expr, complain))
/* We gave an error. */;
else
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr84647.C b/gcc/testsuite/g++.dg/cpp0x/pr84647.C
new file mode 100644
index 00000000000..63292bd8f69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr84647.C
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++11 } }
+
+void (*a)(auto b = c()); // { dg-error "parameter declaration|depend on a template|undeclared name|not declared|default arguments|typeless expression|implicit template" }