This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix failure building LLVM with location wrapper nodes (PR c++/83799)
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Thu, 11 Jan 2018 18:21:21 -0500
- Subject: [PATCH] Fix failure building LLVM with location wrapper nodes (PR c++/83799)
- Authentication-results: sourceware.org; auth=none
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.
Successfully bootstrapped®rtested on x86_64-pc-linux-gnu.
Manually tested with "make s-selftest-c++" (since we don't run the
selftests for cc1plus by default).
OK for trunk?
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.
---
gcc/cp/pt.c | 28 ++++++++++++++++++++++++++++
gcc/testsuite/g++.dg/wrappers/pr83799.C | 18 ++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/wrappers/pr83799.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4f8086b..9517fd9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24219,6 +24219,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
@@ -26657,12 +26659,38 @@ 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;
+
+ /* A USING_DECL in a template should be type-dependent, even if wrapped
+ with a location wrapper (PR c++/83799). */
+
+ ++processing_template_decl;
+
+ tree name = get_identifier ("foo");
+ ASSERT_TRUE (type_dependent_expression_p (name));
+ 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/g++.dg/wrappers/pr83799.C b/gcc/testsuite/g++.dg/wrappers/pr83799.C
new file mode 100644
index 0000000..f93c0ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/wrappers/pr83799.C
@@ -0,0 +1,18 @@
+class DataLayout;
+class TargetLoweringBase {
+ void getTypeLegalizationCost(const DataLayout &DL) const;
+};
+class TargetTransformInfoImplBase {
+ const DataLayout &DL; // this line isn't actually needed to reproduce the issue
+};
+template <typename T>
+class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {};
+template <typename T>
+class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
+ const TargetLoweringBase *getTLI() const;
+ using TargetTransformInfoImplBase::DL;
+ void getArithmeticInstrCost() {
+ const TargetLoweringBase *TLI = getTLI();
+ TLI->getTypeLegalizationCost(DL);
+ }
+};
--
1.8.5.3