diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-01-17 15:56:07 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-01-17 15:56:07 +0000 |
commit | ab612f39a4b756e3a58ec3cb36b4033f84825b9b (patch) | |
tree | 3bc9e71861a2599e6cb0a2ed6e26be602365e358 /gcc | |
parent | f0fbe57d54af9234f441f1332050ef36d0787653 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 38 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/wrappers/pr83799.C | 18 |
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); + } +}; |