aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-01-17 15:56:07 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-01-17 15:56:07 +0000
commitab612f39a4b756e3a58ec3cb36b4033f84825b9b (patch)
tree3bc9e71861a2599e6cb0a2ed6e26be602365e358
parentf0fbe57d54af9234f441f1332050ef36d0787653 (diff)
downloadgcc-ab612f39a4b756e3a58ec3cb36b4033f84825b9b.zip
gcc-ab612f39a4b756e3a58ec3cb36b4033f84825b9b.tar.gz
gcc-ab612f39a4b756e3a58ec3cb36b4033f84825b9b.tar.bz2
Fix failure building LLVM with location wrapper nodes (PR c++/83799)
PR c++/83799 reports a failure building LLVM due to a bogus "no matching function for call to" error at a callsite like this: TLI->getTypeLegalizationCost(DL); where "DL" is from: using TargetTransformInfoImplBase::DL; The root cause is that type_dependent_expression_p on a USING_DECL should return true when processing a template, but after r256448 the the argument at the callsite is a location wrapper around the USING_DECL, and type_dependent_expression_p erroneously returns false for it, as it is comparing tree codes, and failing a match, then looking at types. This prevents cp_parser_postfix_expression from using the "build_min_nt_call_vec" path for handling the call, instead erroneously handling it via build_new_method_call (which fails for this case). This patch fixes the problem by stripping any location wrappers before the various tree code tests in type_dependent_expression_p. It fixes the reduced test case, and the full BasicTargetTransformInfo.ii; after this patch, the assembly generated for that latter case is identical to that generated before r256448. gcc/cp/ChangeLog: PR c++/83799 * pt.c (type_dependent_expression_p): Strip any location wrapper before testing tree codes. (selftest::test_type_dependent_expression_p): New function. (selftest::cp_pt_c_tests): Call it. gcc/testsuite/ChangeLog: PR c++/83799 * g++.dg/wrappers/pr83799.C: New test case. From-SVN: r256796
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c38
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/wrappers/pr83799.C18
4 files changed, 69 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9a48aba..ed44be7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2018-01-17 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/83799
+ * pt.c (type_dependent_expression_p): Strip any location wrapper
+ before testing tree codes.
+ (selftest::test_type_dependent_expression_p): New function.
+ (selftest::cp_pt_c_tests): Call it.
+
2018-01-17 Nathan Sidwell <nathan@acm.org>
PR c++/83739
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0177882..85997e2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24237,6 +24237,8 @@ type_dependent_expression_p (tree expression)
if (expression == NULL_TREE || expression == error_mark_node)
return false;
+ STRIP_ANY_LOCATION_WRAPPER (expression);
+
/* An unresolved name is always dependent. */
if (identifier_p (expression)
|| TREE_CODE (expression) == USING_DECL
@@ -26675,12 +26677,48 @@ test_build_non_dependent_expr ()
build_non_dependent_expr (wrapped_string_lit));
}
+/* Verify that type_dependent_expression_p () works correctly, even
+ in the presence of location wrapper nodes. */
+
+static void
+test_type_dependent_expression_p ()
+{
+ location_t loc = BUILTINS_LOCATION;
+
+ tree name = get_identifier ("foo");
+
+ /* If no templates are involved, nothing is type-dependent. */
+ gcc_assert (!processing_template_decl);
+ ASSERT_FALSE (type_dependent_expression_p (name));
+
+ ++processing_template_decl;
+
+ /* Within a template, an unresolved name is always type-dependent. */
+ ASSERT_TRUE (type_dependent_expression_p (name));
+
+ /* Ensure it copes with NULL_TREE and errors. */
+ ASSERT_FALSE (type_dependent_expression_p (NULL_TREE));
+ ASSERT_FALSE (type_dependent_expression_p (error_mark_node));
+
+ /* A USING_DECL in a template should be type-dependent, even if wrapped
+ with a location wrapper (PR c++/83799). */
+ tree using_decl = build_lang_decl (USING_DECL, name, NULL_TREE);
+ TREE_TYPE (using_decl) = integer_type_node;
+ ASSERT_TRUE (type_dependent_expression_p (using_decl));
+ tree wrapped_using_decl = maybe_wrap_with_location (using_decl, loc);
+ ASSERT_TRUE (location_wrapper_p (wrapped_using_decl));
+ ASSERT_TRUE (type_dependent_expression_p (wrapped_using_decl));
+
+ --processing_template_decl;
+}
+
/* Run all of the selftests within this file. */
void
cp_pt_c_tests ()
{
test_build_non_dependent_expr ();
+ test_type_dependent_expression_p ();
}
} // namespace selftest
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 04a1ffc..74ad98e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-01-17 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/83799
+ * g++.dg/wrappers/pr83799.C: New test case.
+
2018-01-17 Nathan Sidwell <nathan@acm.org>
PR c++/83739
diff --git a/gcc/testsuite/g++.dg/wrappers/pr83799.C b/gcc/testsuite/g++.dg/wrappers/pr83799.C
new file mode 100644
index 0000000..b4f5a69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/wrappers/pr83799.C
@@ -0,0 +1,18 @@
+struct DataLayout;
+struct TargetLoweringBase {
+ void getTypeLegalizationCost(const DataLayout &DL) const;
+};
+struct TargetTransformInfoImplBase {
+ const DataLayout &DL;
+};
+template <typename T>
+struct TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {};
+template <typename T>
+struct BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
+ const TargetLoweringBase *getTLI() const;
+ using TargetTransformInfoImplBase::DL;
+ void getArithmeticInstrCost() {
+ const TargetLoweringBase *TLI = getTLI();
+ TLI->getTypeLegalizationCost(DL);
+ }
+};