Age | Commit message (Collapse) | Author | Files | Lines |
|
The optimization to reuse the same allocator temporary for all string
constructor calls was breaking on this testcase, because the temps were
already in the argument to build_vec_init, and replacing them with
references to one slot got confused with calls at multiple levels (for the
initializer_list backing array, and then again for the array member of the
std::array). Fixed by reusing the whole TARGET_EXPR instead of pulling out
the slot; gimplification ensures that it's only initialized once.
I also moved the check for initializing a std:: class down into the tree
walk, and handle multiple temps within a single array element
initialization.
PR c++/108773
gcc/cp/ChangeLog:
* init.cc (find_allocator_temps_r): New.
(combine_allocator_temps): Replace find_allocator_temp.
(build_vec_init): Adjust.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-array18.C: New test.
* g++.dg/cpp0x/initlist-array19.C: New test.
|
|
The standard was unclear what happens with the transformation of a deduction
guide if the initial template argument deduction fails for a reason other
than not deducing all the arguments; my implementation assumed that the
right thing was to give up on the deduction guide. But in consideration of
CWG2664 this week I realized that we get a better result by just continuing
with an empty set of deductions, so the alias deduction guide is the same as
the original deduction guide plus the deducible constraint.
DR 2664
PR c++/102529
gcc/cp/ChangeLog:
* pt.cc (alias_ctad_tweaks): Continue after deduction failure.
gcc/testsuite/ChangeLog:
* g++.dg/DRs/dr2664.C: New test.
* g++.dg/cpp2a/class-deduction-alias15.C: New test.
|
|
In my initial implementation of alias CTAD, I described a couple of
differences from the specification that I thought would not have a practical
effect; this testcase demonstrates that I was wrong. One difference is
resolved by the CPTK_IS_DEDUCIBLE commit; the other (adding too many of the
alias template parameters to the new deduction guide) is fixed by this
patch.
PR c++/105841
gcc/cp/ChangeLog:
* pt.cc (corresponding_template_parameter_list): Split out...
(corresponding_template_parameter): ...from here.
(find_template_parameters): Factor out...
(find_template_parameter_info::find_in): ...this function.
(find_template_parameter_info::find_in_recursive): New.
(find_template_parameter_info::found): New.
(alias_ctad_tweaks): Only add parms used in the deduced args.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/class-deduction-alias14.C: New test.
Co-authored-by: Michael Spertus <mike@spertus.com>
|
|
I want to have more discussion about the interface before claiming the
__is_deducible name, so for GCC 13 make it internal-only.
gcc/ChangeLog:
* doc/extend.texi: Comment out __is_deducible docs.
gcc/cp/ChangeLog:
* cp-trait.def (IS_DEDUCIBLE): Add space to name.
gcc/testsuite/ChangeLog:
* g++.dg/ext/is_deducible1.C: Guard with
__has_builtin (__is_deducible).
|
|
C++20 class template argument deduction for an alias template involves
adding a constraint that the template arguments for the alias template can
be deduced from the return type of the deduction guide for the underlying
class template. In the standard, this is modeled as defining a class
template with a partial specialization, but it's much more efficient to
implement with a trait that directly tries to perform the deduction.
The first argument to the trait is a template rather than a type, so various
places needed to be adjusted to accommodate that.
PR c++/105841
gcc/ChangeLog:
* doc/extend.texi (Type Traits):: Document __is_deducible.
gcc/cp/ChangeLog:
* cp-trait.def (IS_DEDUCIBLE): New.
* cxx-pretty-print.cc (pp_cxx_trait): Handle non-type.
* parser.cc (cp_parser_trait): Likewise.
* tree.cc (cp_tree_equal): Likewise.
* pt.cc (tsubst_copy_and_build): Likewise.
(type_targs_deducible_from): New.
(alias_ctad_tweaks): Use it.
* semantics.cc (trait_expr_value): Handle CPTK_IS_DEDUCIBLE.
(finish_trait_expr): Likewise.
* constraint.cc (diagnose_trait_expr): Likewise.
* cp-tree.h (type_targs_deducible_from): Declare.
gcc/testsuite/ChangeLog:
* g++.dg/ext/is_deducible1.C: New test.
|
|
|
|
A missed piece of the patch for static operator(): in tsubst_function_decl,
we don't want to replace the first parameter with a new closure pointer if
operator() is static.
PR c++/108526
PR c++/106651
gcc/cp/ChangeLog:
* pt.cc (tsubst_function_decl): Don't replace the closure
parameter if DECL_STATIC_FUNCTION_P.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/static-operator-call5.C: Pass -g.
|
|
Here, -Wdangling-reference triggers where it probably shouldn't, causing
some grief. The code in question uses a reference wrapper with a member
function returning a reference to a subobject of a non-temporary object:
const Plane & meta = fm.planes().inner();
I've tried a few approaches, e.g., checking that the member function's
return type is the same as the type of the enclosing class (which is
the case for member functions returning *this), but that then breaks
Wdangling-reference4.C with std::optional<std::string>.
This patch adjusts do_warn_dangling_reference so that we look through
reference wrapper classes (meaning, has a reference member and a
constructor taking the same reference type, or is std::reference_wrapper
or std::ranges::ref_view) and don't warn for them, supposing that the
member function returns a reference to a non-temporary object.
PR c++/107532
gcc/cp/ChangeLog:
* call.cc (reference_like_class_p): New.
(do_warn_dangling_reference): Add new bool parameter. See through
reference_like_class_p.
gcc/testsuite/ChangeLog:
* g++.dg/warn/Wdangling-reference8.C: New test.
* g++.dg/warn/Wdangling-reference9.C: New test.
|
|
In my recent rtti.cc change I assumed when emitting the support tinfos
that the tinfos for the fundamental types haven't been created yet.
Normally (in libsupc++.a (fundamental_type_info.o)) that is the case,
but as can be seen on the testcase, one can violate it by using typeid
etc. in the same TU and do it before ~__fundamental_type_info ()
definition.
The following patch fixes that by popping from unemitted_tinfo_decls
only in the normal case when it is there, and treating non-NULL
DECL_INITIAL on a tinfo node as indication that emit_tinfo_decl has
processed it already.
2023-03-07 Jakub Jelinek <jakub@redhat.com>
PR c++/109042
* rtti.cc (emit_support_tinfo_1): Don't assert that last
unemitted_tinfo_decls element is tinfo, instead pop from it only in
that case.
* decl2.cc (c_parse_final_cleanups): Don't call emit_tinfo_decl
for unemitted_tinfO_decls which have already non-NULL DECL_INITIAL.
* g++.dg/rtti/pr109042.C: New test.
|
|
When processing a noexcept, constructors aren't elided: build_over_call
has
/* It's unsafe to elide the constructor when handling
a noexcept-expression, it may evaluate to the wrong
value (c++/53025). */
&& (force_elide || cp_noexcept_operand == 0))
so the assert I added recently needs to be relaxed a little bit.
PR c++/109030
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_call_expression): Relax assert.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/noexcept77.C: New test.
|
|
Similarly to PR107938, this also started with r11-557, whereby cp_finish_decl
can call check_initializer even in a template for a constexpr initializer.
Here we are rejecting
extern const Q q;
template<int>
constexpr auto p = q(0);
even though q has a constexpr operator(). It's deemed non-const by
decl_maybe_constant_var_p because even though 'q' is const it is not
of integral/enum type.
If fun is not a function pointer, we don't know if we're using it as an
lvalue or rvalue, so with this patch we pass 'any' for want_rval. With
that, p_c_e/VAR_DECL doesn't flat out reject the underlying VAR_DECL.
PR c++/107939
gcc/cp/ChangeLog:
* constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Pass
'any' when recursing on a VAR_DECL and not a pointer to function.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/var-templ74.C: Remove dg-error.
* g++.dg/cpp1y/var-templ77.C: New test.
|
|
|
|
The stmtexpr19.C testcase used to be rejected as it has a static
variable in statement expression in constexpr context, but as that
static variable is initialized by constant expression, when P2647R1
was implemented we agreed to make it valid.
Now, as reported, the testcase compiles fine, but doesn't actually link
because the static variable isn't defined anywhere, and with -flto ICEs
because of this problem. This is because we never
varpool_node::finalize_decl those vars, the constant expression in which
the DECL_EXPR is present for the static VAR_DECL is folded (constant
evaluated) into just the address of the VAR_DECL.
Now, similar testcase included below (do we want to include it in the
testsuite too?) works fine, because in
cp_finish_decl -> make_rtl_for_nonlocal_decl
we have since PR70353 fix:
/* We defer emission of local statics until the corresponding
DECL_EXPR is expanded. But with constexpr its function might never
be expanded, so go ahead and tell cgraph about the variable now. */
defer_p = ((DECL_FUNCTION_SCOPE_P (decl)
&& !var_in_maybe_constexpr_fn (decl))
|| DECL_VIRTUAL_P (decl));
and so don't defer them in constexpr/consteval functions. The following
patch calls rest_of_decl_compilation which make_rtl_for_nonlocal_decl didn't
call when encountering DECL_EXPRs of such vars during constant evaluation
if they weren't finalized yet.
2023-03-04 Jakub Jelinek <jakub@redhat.com>
PR c++/108702
* constexpr.cc: Include toplev.h.
(cxx_eval_constant_expression) <case DECL_EXPR>: When seeing a local
static initialized by constant expression outside of a constexpr
function which has been deferred by make_rtl_for_nonlocal_decl,
call rest_of_decl_compilation on it.
* g++.dg/ext/stmtexpr19.C: Use dg-do link rather than dg-do compile.
|
|
|
|
In order to fix PR100295, r13-4730-g18499b9f848707 attempted to make
extract_local_specs walk the given pattern twice, ignoring unevaluated
operands the first time around so that we prefer to process a local
specialization in an evaluated context if it appears in one (we process
each local specialization once even if it appears multiple times in the
pattern).
But there's a thinko in the patch, namely that we don't actually walk
the pattern twice since we don't clear the visited set for the second
walk (to avoid processing a local specialization twice) and so the root
node (and any node leading up to an unevaluated operand) is considered
visited already. So the patch effectively made extract_local_specs
ignore unevaluated operands altogether, which this testcase demonstrates
isn't quite safe (extract_local_specs never sees 'aa' and we don't record
its local specialization, so later we try to specialize 'aa' on the spot
with the args {{int},{17}} which causes us to nonsensically substitute
its auto with 17.)
This patch fixes this by refining the second walk to start from the
trees we skipped over during the first walk.
PR c++/108998
gcc/cp/ChangeLog:
* pt.cc (el_data::skipped_trees): New data member.
(extract_locals_r): Push to skipped_trees any unevaluated
contexts that we skipped over.
(extract_local_specs): For the second walk, start from each
tree in skipped_trees.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-generic11.C: New test.
|
|
When TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, when
we warn about comparing a pointer-to-member-function with NULL, we
also warn about comparing the pointer-to-function extracted from it
with NULL, which is redundant. Suppress the redundant warning.
for gcc/cp/ChangeLog
* typeck.cc (cp_build_binary_op): Suppress redundant warning
for pfn null test in pmfn test with vbit-in-delta.
|
|
|
|
ia32 with -mno-sse2 [PR108883]
_Float16 and decltype(0.0bf16) types are on x86 supported only with
-msse2. On x86_64 that is the default, but on ia32 it is not.
We should still emit fundamental type tinfo for those types in
libsupc++.a/libstdc++.*, regardless of whether libsupc++/libstdc++
is compiled with -msse2 or not, as user programs can be compiled
with different ISA flags from libsupc++/libstdc++ and if they
are compiled with -msse2 and use std::float16_t or std::bfloat16_t
and need RTTI for it, it should work out of the box. Furthermore,
libstdc++ ABI on ia32 shouldn't depend on whether the library
is compiled with -mno-sse or -msse2.
Unfortunately, just hacking up libsupc++ Makefile/configure so that
a single source is compiled with -msse2 isn't appropriate, because
that TU emits also code and the code should be able to run on CPUs
which libstdc++ supports. We could add [[gnu::attribute ("no-sse2")]]
there perhaps conditionally, but it all gets quite ugly.
The following patch instead adds a target hook which allows the backend
to temporarily tweak registered types such that emit_support_tinfos
emits whatever is needed.
Additionally, it makes emit_support_tinfos_1 call emit_tinfo_decl
immediately, so that temporarily created dummy types for emit_support_tinfo
purposes only can be nullified again afterwards. And removes the
previous fallback_* types used for dfloat*_type_node tinfos even when
decimal types aren't supported.
2023-03-03 Jakub Jelinek <jakub@redhat.com>
PR target/108883
gcc/
* target.h (emit_support_tinfos_callback): New typedef.
* targhooks.h (default_emit_support_tinfos): Declare.
* targhooks.cc (default_emit_support_tinfos): New function.
* target.def (emit_support_tinfos): New target hook.
* doc/tm.texi.in (emit_support_tinfos): Document it.
* doc/tm.texi: Regenerated.
* config/i386/i386.cc (ix86_emit_support_tinfos): New function.
(TARGET_EMIT_SUPPORT_TINFOS): Redefine.
gcc/cp/
* cp-tree.h (enum cp_tree_index): Remove CPTI_FALLBACK_DFLOAT*_TYPE
enumerators.
(fallback_dfloat32_type, fallback_dfloat64_type,
fallback_dfloat128_type): Remove.
* rtti.cc (emit_support_tinfo_1): If not emitted already, call
emit_tinfo_decl and remove from unemitted_tinfo_decls right away.
(emit_support_tinfos): Move &dfloat*_type_node from fundamentals array
into new fundamentals_with_fallback array. Call emit_support_tinfo_1
on elements of that array too, with the difference that if
the type is NULL, use a fallback REAL_TYPE for it temporarily.
Drop the !targetm.decimal_float_supported_p () handling. Call
targetm.emit_support_tinfos at the end.
* mangle.cc (write_builtin_type): Remove references to
fallback_dfloat*_type. Handle bfloat16_type_node mangling.
|
|
We should also fold the overall initializer passed to cp_fully_fold_init
with mce_false, which allows folding of the copy-initialization of
'a1' in the below testcase (the initializer here is an AGGR_INIT_EXPR).
Unfortunately this doesn't help with direct- or default-initialization
because we don't call cp_fully_fold_init in that case, and even if we
did the initializer in that case is expressed as a bare CALL_EXPR
instead of an AGGR_INIT_EXPR, which cp_fully_fold_init can't really
fold.
PR c++/108243
PR c++/97553
gcc/cp/ChangeLog:
* cp-gimplify.cc (cp_fully_fold): Add an internal overload that
additionally takes and propagate an mce_value parameter, and
define the existing public overload in terms of it.
(cp_fully_fold_init): Pass mce_false to cp_fully_fold.
gcc/testsuite/ChangeLog:
* g++.dg/opt/is_constant_evaluated3.C: New test.
|
|
According to [basic.start.static]/2 and [expr.const]/2, a variable
with static storage duration initialized with a constant initializer
has constant initialization, and such an initializer is manifestly
constant-evaluated.
For copy initialization, we're already getting this right because in
that case check_initializer would consistently call store_init_value,
which for TREE_STATIC variables calls fold_non_dependent_init with
m_c_e=true.
But for direct (or default) initialization, check_initializer doesn't
always call store_init_value. We instead however always call
maybe_constant_init from expand_default_init[1], albeit with m_c_e=false
which means we don't get the "manifestly constant-evaluated" part right
for non-copy-init.
This patch fixes this by setting m_c_e=true in maybe_constant_init for
static storage duration variables, mainly for benefit of the call
to maybe_constant_init from expand_default_init.
[1]: this maybe_constant_init call isn't reached in the copy-init
case because there init is a CONSTRUCTOR rather than a TREE_LIST,
and so we exit early from expand_default_init, returning an INIT_EXPR.
This INIT_EXPR is ultimately what causes us to consistently hit the
store_init_value code path from check_initializer in the copy-init case.
PR c++/108243
gcc/cp/ChangeLog:
* constexpr.cc (maybe_constant_init_1): Override
manifestly_const_eval to true if is_static.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/is-constant-evaluated14.C: New test.
|
|
Before IMPORTED_DECL has been introduced in PR37410, we used to emit correct
DW_AT_decl_line on DW_TAG_imported_module on the testcase below, after that
change we haven't emitted it at all for a while and after some time
started emitting incorrect locus, in particular the location of } closing
the function.
The problem is that while we have correct EXPR_LOCATION on the USING_STMT,
when genericizing that USING_STMT into IMPORTED_DECL we don't copy the
location to DECL_SOURCE_LOCATION, so it gets whatever input_location happens
to be when it is created.
2023-03-02 Jakub Jelinek <jakub@redhat.com>
PR debug/108716
* cp-gimplify.cc (cp_genericize_r) <case USING_STMT>: Set
DECL_SOURCE_LOCATION on IMPORTED_DECL to expression location
of USING_STMT or input_location.
* g++.dg/debug/dwarf2/pr108716.C: New test.
|
|
-Wmismatched-tags warns about the (harmless) struct/class mismatch.
For, e.g.,
template<typename T> struct A { };
class A<int> a;
it works by adding A<T> to the class2loc hash table while parsing the
class-head and then, while parsing the elaborate type-specifier, we
add A<int>. At the end of c_parse_file we go through the table and
warn about the class-key mismatches. In this PR we crash though; we
have
template<typename T> struct A {
template<typename U> struct W { };
};
struct A<int>::W<int> w; // #1
where while parsing A and #1 we've stashed
A<T>
A<T>::W<U>
A<int>::W<int>
into class2loc. Then in class_decl_loc_t::diag_mismatched_tags TYPE
is A<int>::W<int>, and specialization_of gets us A<int>::W<U>, which
is not in class2loc, so we crash on gcc_assert (cdlguide). But it's
OK not to have found A<int>::W<U>, we should just look one "level" up,
that is, A<T>::W<U>.
It's important to handle class specializations, so e.g.
template<>
struct A<char> {
template<typename U>
class W { };
};
where W's class-key is different than in the primary template above,
so we should warn depending on whether we're looking into A<char>
or into a different instantiation.
PR c++/106259
gcc/cp/ChangeLog:
* parser.cc (class_decl_loc_t::diag_mismatched_tags): If the first
lookup of SPEC didn't find anything, try to look for
most_general_template.
gcc/testsuite/ChangeLog:
* g++.dg/warn/Wmismatched-tags-11.C: New test.
|
|
range for loops [PR105839]
The PR108503 temporary DECL_HAS_VALUE_EXPR_P clearing code can ICE
during recovery, because cp_finish_decomp when it detects errors and
reports them clears DECL_HAS_VALUE_EXPR_P, clears DECL_VALUE_EXPR and
sets TREE_TYPE of the structured binding vars to error_mark_node.
The PR108503 code had an assertion that DECL_HAS_VALUE_EXPR_P is set
so that it can clear it and restore later.
The following patch allows DECL_HAS_VALUE_EXPR_P to be unset if
type is error_mark_node and doesn't set it again in that case.
2023-03-02 Jakub Jelinek <jakub@redhat.com>
PR c++/105839
* parser.cc (cp_convert_omp_range_for): Allow in assert
decomp_first_name without DECL_HAS_VALUE_EXPR_P if it has
error_mark_node type.
(cp_finish_omp_range_for): Don't set DECL_HAS_VALUE_EXPR_P back
on decls which have error_mark_node type.
* g++.dg/gomp/pr105839-1.C: New test.
* g++.dg/gomp/pr105839-2.C: New test.
|
|
|
|
Here we're attempting to evaluate a PTRMEM_CST in a class that hasn't
been completed yet, but that doesn't work:
/* We can't lower this until the class is complete. */
if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
return cst;
and then this unlowered PTRMEM_CST is used as EXPR in
tree op1 = build_nop (ptrdiff_type_node, expr);
and we crash in a subsequent cp_fold_convert which gets type=ptrdiff_type_node,
expr=PTRMEM_CST and does
else if (TREE_CODE (expr) == PTRMEM_CST
&& same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
PTRMEM_CST_CLASS (expr)))
where TYPE_PTRMEM_CLASS_TYPE (type) is going to crash since the type
is ptrdiff_type_node. We could just add a TYPE_PTRMEM_P check before
accessing TYPE_PTRMEM_CLASS_TYPE but I think it's nicer to explain why
we couldn't evaluate the expression.
PR c++/107574
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_constant_expression): Emit an error when
a PTRMEM_CST cannot be evaluated.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/ptrmem-cst1.C: New test.
|
|
This patch introduces a convenience wrapper tsubst_scope for tsubst'ing
into a type with tf_qualifying_scope set, and makes suitable callers use
it instead of explicitly setting tf_qualifying_scope. This patch also
makes tsubst_copy immediately delegate to tsubst for all type trees,
which allows tsubst_copy to be oblivious to the tf_qualifying_scope flag.
gcc/cp/ChangeLog:
* pt.cc (tsubst_scope): Define.
(tsubst_decl) <case USING_DECL>: Call tsubst_scope instead of
calling tsubst_scope with tf_qualifying_scope set.
(tsubst_qualified_id): Call tsubst_scope instead of
calling tsubst with tf_qualifying_scope set.
(tsubst_copy): Immediately delegate to tsubst for all TYPE_P
trees. Remove tf_qualifying_scope manipulation.
<case SCOPE_REF>: Call tsubst_scope instead of calling
tsubst with tf_qualifying_scope set.
|
|
Here we're mishandling the unevaluated array new-expressions due to a
supposed non-constant array size ever since r12-5253-g4df7f8c79835d569
made us no longer perform constant evaluation of non-manifestly-constant
expressions within unevaluated contexts. This shouldn't make a difference
here since the array sizes are constant literals, except they're expressed
as NON_LVALUE_EXPR location wrappers around INTEGER_CST, wrappers which
used to get stripped as part of constant evaluation and now no longer do.
Moreover it means build_vec_init can't constant fold the MINUS_EXPR
'maxindex' passed from build_new_1 when in an unevaluated context (since
it tries reducing it via maybe_constant_value called with mce_unknown).
This patch fixes these issues by making maybe_constant_value (and
fold_non_dependent_expr) try folding an unevaluated non-manifestly-constant
operand via fold(), as long as it simplifies to a simple constant, rather
than doing no simplification at all. This covers e.g. simple arithmetic
and casts including stripping of location wrappers around INTEGER_CST.
In passing, this patch also fixes maybe_constant_value to avoid constant
evaluating an unevaluated operand when called with mce_false, by adjusting
the early exit test appropriately.
Co-authored-by: Jason Merrill <jason@redhat.com>
PR c++/108219
PR c++/108218
gcc/cp/ChangeLog:
* constexpr.cc (fold_to_constant): Define.
(maybe_constant_value): Move up early exit test for unevaluated
operands. Try reducing an unevaluated operand to a constant via
fold_to_constant.
(fold_non_dependent_expr_template): Add early exit test for
CONSTANT_CLASS_P nodes. Try reducing an unevaluated operand
to a constant via fold_to_constant.
* cp-tree.h (fold_to_constant): Declare.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/new6.C: New test.
* g++.dg/cpp2a/concepts-new1.C: New test.
|
|
The r13-2965-g73d9b0e5947e16 change changed the line touched in this patch
from
return RECUR (tmp, want_rval);
to
return RECUR (DECL_INITIAL (tmp), want_rval);
This is on DECL_EXPR handling code, where tmp can be lots of different
trees and DECL_INITIAL unfortunately also means different things on
different trees.
It is the initializer on VAR_DECL, DECL_ARG_TYPE on PARM_DECLs (though
those are unlikely to have DECL_EXPRs), for FUNCTION_DECLs the body,
..., USING_DECL_DECLS on USING_DECLs and DECL_FRIENDLIST on TYPE_DECLs.
The testcase below ICEs because we have a DECL_EXPR for TYPE_DECL
which has non-NULL DECL_FRIENDLIST and we certainly can't recurse on
the friend list.
The following patch will RECUR on DECL_INITIAL only for VAR_DECLs and
for anything else just return true.
2023-03-01 Jakub Jelinek <jakub@redhat.com>
PR c++/108606
* constexpr.cc (potential_constant_expression_1) <case DECL_EXPR>:
Only recurse on DECL_INITIAL (tmp) if tmp is a VAR_DECL, otherwise
just return true.
* g++.dg/cpp1y/pr108606.C: New test.
|
|
|
|
Here we're treating deeming the non-dependent variable template-id
tag<int> as dependent ever since r226642 gave variable TEMPLATE_ID_EXPR
an empty type, which causes the call to finish_template_variable from
finish_id_expression_1 to be unreachable at template parse time. Thus
we're led into thinking tag<int>.var<void> refers to a dependent name.
This patch fixes this by making finish_id_expression_1 instantiate a
variable template-id as long as it's not dependent according to the
dependence test in lookup_and_finish_template_variable rather than
according to type_dependent_expression_p.
PR c++/108848
gcc/cp/ChangeLog:
* pt.cc (finish_template_variable): Move dependence check
to here from ...
(lookup_and_finish_template_variable): ... here.
* semantics.cc (finish_id_expression_1): Call
finish_template_variable sooner, before (and regardless of) the
type_dependent_expression_p test.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/noexcept1.C: Don't expect a bogus "different
exception specifier" error. Expect a separate "not usable
in a constant expression" error.
* g++.dg/cpp1y/var-templ75.C: New test.
* g++.dg/cpp1y/var-templ76.C: New test.
|
|
In this test, we get a bogus error because we failed to deduce the auto in
constexpr auto is_pointer_v = is_pointer<Tp>::value;
to bool. Then ensure_literal_type_for_constexpr_object thinks the object
isn't literal and an error is reported.
This is another case of the interaction between tf_partial and 'auto',
where the auto was not reduced so the deduction failed. In more detail:
we have
Wrap1<int>()
in the code and we need to perform OR -> fn_type_unification. The targ
list is incomplete, so we do
tsubst_flags_t ecomplain = complain | tf_partial | tf_fndecl_type;
fntype = tsubst (TREE_TYPE (fn), explicit_targs, ecomplain, NULL_TREE);
where TREE_TYPE (fn) is struct integral_constant <T402> (void). Then
we substitute the return type, which results in tsubsting is_pointer_v<int>.
is_pointer_v is a variable template with a placeholder type:
template <class Tp>
constexpr auto is_pointer_v = is_pointer<Tp>::value;
so we find ourselves in lookup_and_finish_template_variable. tf_partial is
still set, so finish_template_variable -> instantiate_template -> tsubst
won't reduce the level of auto. But then we do mark_used which eventually
calls do_auto_deduction which clears tf_partial, because we want to replace
the auto now. But we hadn't reduced auto's level so this fails. And
since we're not in an immediate context, we emit a hard error.
I suppose that when we reach lookup_and_finish_template_variable it's
probably time to clear tf_partial. (I added an assert and our testsuite
doesn't have a test whereby we get to lookup_and_finish_template_variable
while tf_partial is still active.)
PR c++/108550
gcc/cp/ChangeLog:
* pt.cc (lookup_and_finish_template_variable): Clear tf_partial.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/var-templ70.C: New test.
* g++.dg/cpp1y/var-templ71.C: New test.
* g++.dg/cpp1y/var-templ72.C: New test.
|
|
|
|
In constexpr-nsdmi3.C, with -fno-elide-constructors, we don't elide
the Y::Y(const Y&) call used to initialize o.c. So store_init_value
-> cxx_constant_init must constexpr-evaluate the call to Y::Y(const Y&)
in cxx_eval_call_expression. It's a trivial function, so we do the
"Shortcut trivial constructor/op=" code and rather than evaluating
the function, we just create an assignment
o.c = *(const struct Y &) (const struct Y *) &(&<PLACEHOLDER_EXPR struct X>)->b
which is a MODIFY_EXPR, so the preeval code in cxx_eval_store_expression
clears .ctor and .object, therefore we can't replace the PLACEHOLDER_EXPR
whereupon we crash at
/* A placeholder without a referent. We can get here when
checking whether NSDMIs are noexcept, or in massage_init_elt;
just say it's non-constant for now. */
gcc_assert (ctx->quiet);
The PLACEHOLDER_EXPR can also be on the LHS as in constexpr-nsdmi10.C.
I don't think we can do much here, but I noticed that the whole
trivial_fn_p (fun) block is only entered when -fno-elide-constructors.
This is true since GCC 9; it wasn't easy to bisect what changes made it
so, but r240845 is probably one of them. -fno-elide-constructors is an
option for experiments only so it's not clear to me why we'd still want
to shortcut trivial constructor/op=. I propose to remove the code and
add a checking assert to make sure we're not getting a trivial_fn_p
unless -fno-elide-constructors.
PR c++/101073
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_call_expression): Replace shortcutting trivial
constructor/op= with a checking assert.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/constexpr-nsdmi3.C: New test.
* g++.dg/cpp1y/constexpr-nsdmi10.C: New test.
|
|
Here we crash in is_capture_proxy:
/* Location wrappers should be stripped or otherwise handled by the
caller before using this predicate. */
gcc_checking_assert (!location_wrapper_p (decl));
We only crash with the redundant capture:
int abyPage = [=, abyPage] { ... }
because prune_lambda_captures is only called when there was a default
capture, and with [=] only abyPage won't be in LAMBDA_EXPR_CAPTURE_LIST.
The problem is that LAMBDA_CAPTURE_EXPLICIT_P wasn't propagated
correctly and so var_to_maybe_prune proceeded where it shouldn't.
Co-Authored by: Patrick Palka <ppalka@redhat.com>
PR c++/108829
gcc/cp/ChangeLog:
* pt.cc (prepend_one_capture): Set LAMBDA_CAPTURE_EXPLICIT_P.
(tsubst_lambda_expr): Pass LAMBDA_CAPTURE_EXPLICIT_P to
prepend_one_capture.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/lambda/lambda-108829-2.C: New test.
* g++.dg/cpp0x/lambda/lambda-108829.C: New test.
|
|
|
|
For a long time, people have expected to be able to write
static_assert (false) in a template and only have it diagnosed if the
template is instantiated, but we (and other implementations) gave an error
about the uninstantiated template because the standard says that if no valid
instantiation of the template is possible, the program is ill-formed, no
diagnostic required, and we try to diagnose IFNDR things when feasible.
At the meeting last week we were looking at CWG2518, which wanted to specify
that an implementation must not accept a program containing a failing #error
or static_assert. We also looked at P2593, which proposed allowing
static_assert in an uninstantiated template. We ended up combining these
two in order to avoid requiring implementations to reject programs with
static_assert (false) in uninstantiated templates.
The committee accepted this as a DR, so I'm making the change to all
standard modes. This behavior was also conformant previously, since no
diagnostic was required in this case.
We continue to diagnose non-constant or otherwise ill-formed conditions, so
no changes to existing tests were needed.
DR 2518
PR c++/52809
PR c++/53638
PR c++/87389
PR c++/89741
PR c++/92099
PR c++/104041
PR c++/104691
gcc/cp/ChangeLog:
* semantics.cc (finish_static_assert): Don't diagnose in
template context.
gcc/testsuite/ChangeLog:
* g++.dg/DRs/dr2518.C: New test.
|
|
|
|
This PR illustrates that __builtin_is_constant_evaluated currently acts
as an optimization barrier for our speculative constexpr evaluation,
since we don't want to prematurely fold the builtin to false before the
expression in question undergoes manifestly constant evaluation if
appropriate (in which case the builtin must instead be folded to true).
This patch fixes this by permitting __builtin_is_constant_evaluated to
get folded as false at appropiate points, namely during cp_fold_function
and cp_fully_fold_init where we know we're done with manifestly constant
evaluation. The function cp_fold gets a flags parameter that controls
whether we pass mce_false or mce_unknown to maybe_constant_value when
folding a CALL_EXPR.
PR c++/108243
PR c++/97553
gcc/cp/ChangeLog:
* cp-gimplify.cc (enum fold_flags): Define.
(fold_flags_t): Declare.
(cp_fold_data::genericize): Replace this data member with ...
(cp_fold_data::fold_flags): ... this.
(cp_fold_r): Adjust use of cp_fold_data and calls to cp_fold.
(cp_fold_function): Likewise.
(cp_fold_maybe_rvalue): Add an internal overload that
additionally takes and propagates a fold_flags_t parameter, and
define the existing public overload in terms of it.
(cp_fold_rvalue): Likewise.
(cp_fully_fold_init): Adjust use of cp_fold_data.
(fold_cache): Replace with ...
(fold_caches): ... this 2-element array of caches.
(get_fold_cache): Define.
(clear_fold_cache): Adjust.
(cp_fold): Add fold_flags_t parameter. Use get_fold_cache.
Pass flags to calls to cp_fold, cp_fold_rvalue and
cp_fold_maybe_rvalue.
<case CALL_EXPR>: If ff_mce_false is set, fold
__builtin_is_constant_evaluated to false and pass mce_false to
maybe_constant_value.
gcc/testsuite/ChangeLog:
* g++.dg/opt/is_constant_evaluated1.C: New test.
* g++.dg/opt/is_constant_evaluated2.C: New test.
|
|
This patch converts the constexpr machinery's manifestly_const_eval flag
into a tri-state enum to allow us to express wanting to fold
__builtin_is_constant_evaluated to false via speculative constexpr
evaluation. For now, only the maybe_constant_value entry point is
changed to take this enum; the others continue to take bool. The
subsequent patch will teach cp_fold (which uses maybe_constant_value) to
fold the builtin to false when called from cp_fold_function and
cp_fully_fold_init.
gcc/cp/ChangeLog:
* constexpr.cc (constexpr_call::manifestly_const_eval): Give
it type int instead of bool.
(constexpr_ctx::manifestly_const_eval): Give it type mce_value
instead of bool.
(cxx_eval_builtin_function_call): Adjust after making
manifestly_const_eval tri-state.
(cxx_eval_call_expression): Likewise.
(cxx_eval_binary_expression): Likewise.
(cxx_eval_conditional_expression): Likewise.
(cxx_eval_constant_expression): Likewise.
(cxx_eval_outermost_constant_expr): Likewise.
(cxx_constant_value): Likewise.
(cxx_constant_dtor): Likewise.
(maybe_constant_value): Give manifestly_const_eval parameter
type mce_value instead of bool and adjust accordingly.
(fold_non_dependent_expr_template): Adjust call
to cxx_eval_outermost_constant_expr.
(fold_non_dependent_expr): Likewise.
(maybe_constant_init_1): Likewise.
* constraint.cc (satisfy_atom): Adjust call to
maybe_constant_value.
* cp-tree.h (enum class mce_value): Define.
(maybe_constant_value): Adjust manifestly_const_eval parameter
type and default argument.
* decl.cc (compute_array_index_type_loc): Adjust call to
maybe_constant_value.
* pt.cc (convert_nontype_argument): Likewise.
|
|
|
|
Currently when resolving a TYPENAME_TYPE for 'typename T::m' via
make_typename_type, we consider only type bindings of 'm' and ignore
non-type ones. But [temp.res.general]/3 says, in a note, "the usual
qualified name lookup ([basic.lookup.qual]) applies even in the presence
of 'typename'", and qualified name lookup doesn't discriminate between
type and non-type bindings. So when resolving such a TYPENAME_TYPE
we want the lookup to consider all bindings.
An exception is when we have a TYPENAME_TYPE corresponding to the
qualifying scope of the :: scope resolution operator, such as 'T::type'
in 'T::type::m'. In that case, [basic.lookup.qual]/1 applies, and
lookup for such a TYPENAME_TYPE must ignore non-type bindings. So in
order to correctly handle all cases, make_typename_type needs an
additional flag controlling whether to restrict the lookup.
To that end this patch adds a new tsubst flag tf_qualifying_scope
denoting whether we're substituting the LHS of the :: operator,
which make_typename_type will look for to conditionally restrict the
lookup to type bindings (by default we want to consider all bindings).
So in contexts such as substituting into the scope of TYPENAME_TYPE,
SCOPE_REF or USING_DECL we simply pass tf_qualifying_scope to the
relevant tsubst / tsubst_copy call, and if that scope is a TYPENAME_TYPE
then make_typename_type will restrict the lookup accordingly. This flag
is intended to apply only to overall scope (TYPENAME_TYPE or not) so we
must be careful to clear the flag to avoid propagating it when recursing
into sub-trees of the scope.
PR c++/107773
gcc/cp/ChangeLog:
* cp-tree.h (enum tsubst_flags): New flag tf_qualifying_scope.
* decl.cc (make_typename_type): Use lookup_member instead of
lookup_field. If tf_qualifying_scope is set, pass want_type=true
instead of =false to lookup_member. Generalize format specifier
in diagnostic to handle both type and non-type bindings.
* pt.cc (tsubst_aggr_type_1): Clear tf_qualifying_scope. Tidy
the function.
(tsubst_decl) <case USING_DECL>: Set tf_qualifying_scope when
substituting USING_DECL_SCOPE.
(tsubst): Clear tf_qualifying_scope right away and remember if
it was set. Do the same for tf_tst_ok sooner.
<case TYPENAME_TYPE>: Set tf_qualifying_scope when substituting
TYPE_CONTEXT. Pass tf_qualifying_scope to make_typename_type
if it was set.
(tsubst_qualified_id): Set tf_qualifying_scope when substituting
the scope.
(tsubst_copy): Clear tf_qualifying_scope and remember if it was
set.
<case SCOPE_REF>: Set tf_qualifying_scope when substituting the
scope.
<case *_TYPE>: Pass tf_qualifying_scope to tsubst if it was set.
* search.cc (lookup_member): Document default argument.
gcc/testsuite/ChangeLog:
* g++.dg/template/typename24.C: New test.
* g++.dg/template/typename25.C: New test.
* g++.dg/template/typename25a.C: New test.
* g++.dg/template/typename26.C: New test.
|
|
Many functions defined in our headers are declared 'static inline' which
is a C idiom whose use predates our move to C++ as the implementation
language. But in C++ the inline keyword is more than just a compiler
hint, and is sufficient to give the function the intended semantics.
In fact declaring a function both static and inline is a pessimization
since static effectively disables the desired definition merging
behavior enabled by inline, and is also a source of (harmless) ODR
violations when a static inline function gets called from a non-static
inline one (such as tree_operand_check calling tree_operand_length).
This patch mechanically fixes the vast majority of occurrences of this
anti-pattern throughout the compiler's headers via the command line
sed -i 's/^static inline/inline/g' gcc/*.h gcc/*/*.h
There's also a manual change to remove the redundant declarations
of is_ivar and lookup_category in gcc/objc/objc-act.cc which would
otherwise conflict with their modified definitions in objc-act.h
(due to the difference in staticness).
Besides fixing some ODR violations, this speeds up stage1 cc1plus by
about 2% and reduces the size of its text segment by 1.5MB.
gcc/ChangeLog:
* addresses.h: Mechanically drop 'static' from 'static inline'
functions via s/^static inline/inline/g.
* asan.h: Likewise.
* attribs.h: Likewise.
* basic-block.h: Likewise.
* bitmap.h: Likewise.
* cfghooks.h: Likewise.
* cfgloop.h: Likewise.
* cgraph.h: Likewise.
* cselib.h: Likewise.
* data-streamer.h: Likewise.
* debug.h: Likewise.
* df.h: Likewise.
* diagnostic.h: Likewise.
* dominance.h: Likewise.
* dumpfile.h: Likewise.
* emit-rtl.h: Likewise.
* except.h: Likewise.
* expmed.h: Likewise.
* expr.h: Likewise.
* fixed-value.h: Likewise.
* gengtype.h: Likewise.
* gimple-expr.h: Likewise.
* gimple-iterator.h: Likewise.
* gimple-predict.h: Likewise.
* gimple-range-fold.h: Likewise.
* gimple-ssa.h: Likewise.
* gimple.h: Likewise.
* graphite.h: Likewise.
* hard-reg-set.h: Likewise.
* hash-map.h: Likewise.
* hash-set.h: Likewise.
* hash-table.h: Likewise.
* hwint.h: Likewise.
* input.h: Likewise.
* insn-addr.h: Likewise.
* internal-fn.h: Likewise.
* ipa-fnsummary.h: Likewise.
* ipa-icf-gimple.h: Likewise.
* ipa-inline.h: Likewise.
* ipa-modref.h: Likewise.
* ipa-prop.h: Likewise.
* ira-int.h: Likewise.
* ira.h: Likewise.
* lra-int.h: Likewise.
* lra.h: Likewise.
* lto-streamer.h: Likewise.
* memmodel.h: Likewise.
* omp-general.h: Likewise.
* optabs-query.h: Likewise.
* optabs.h: Likewise.
* plugin.h: Likewise.
* pretty-print.h: Likewise.
* range.h: Likewise.
* read-md.h: Likewise.
* recog.h: Likewise.
* regs.h: Likewise.
* rtl-iter.h: Likewise.
* rtl.h: Likewise.
* sbitmap.h: Likewise.
* sched-int.h: Likewise.
* sel-sched-ir.h: Likewise.
* sese.h: Likewise.
* sparseset.h: Likewise.
* ssa-iterators.h: Likewise.
* system.h: Likewise.
* target-globals.h: Likewise.
* target.h: Likewise.
* timevar.h: Likewise.
* tree-chrec.h: Likewise.
* tree-data-ref.h: Likewise.
* tree-iterator.h: Likewise.
* tree-outof-ssa.h: Likewise.
* tree-phinodes.h: Likewise.
* tree-scalar-evolution.h: Likewise.
* tree-sra.h: Likewise.
* tree-ssa-alias.h: Likewise.
* tree-ssa-live.h: Likewise.
* tree-ssa-loop-manip.h: Likewise.
* tree-ssa-loop.h: Likewise.
* tree-ssa-operands.h: Likewise.
* tree-ssa-propagate.h: Likewise.
* tree-ssa-sccvn.h: Likewise.
* tree-ssa.h: Likewise.
* tree-ssanames.h: Likewise.
* tree-streamer.h: Likewise.
* tree-switch-conversion.h: Likewise.
* tree-vectorizer.h: Likewise.
* tree.h: Likewise.
* wide-int.h: Likewise.
gcc/c-family/ChangeLog:
* c-common.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
gcc/c/ChangeLog:
* c-parser.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
gcc/cp/ChangeLog:
* cp-tree.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
gcc/fortran/ChangeLog:
* gfortran.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
gcc/jit/ChangeLog:
* jit-dejagnu.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
* jit-recording.h: Likewise.
gcc/objc/ChangeLog:
* objc-act.h: Mechanically drop static from static inline
functions via s/^static inline/inline/g.
* objc-map.h: Likewise.
* objc-act.cc: Remove the redundant redeclarations of is_ivar
and lookup_category.
|
|
|
|
joust_maybe_elide_copy checks that the last conversion in the ICS for
the first argument is ck_ref_bind, which is reasonable, because we've
checked that we're dealing with a copy/move constructor. But it can
also happen that we couldn't figure out which conversion function is
better to convert the argument, as in this testcase: joust couldn't
decide if we should go with
operator foo &()
or
operator foo const &()
so we get a ck_ambig, which then upsets joust_maybe_elide_copy. Since
a ck_ambig can validly occur, I think we should just return early, as
in the patch below.
PR c++/106675
gcc/cp/ChangeLog:
* call.cc (joust_maybe_elide_copy): Return false for ck_ambig.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/overload-conv-5.C: New test.
|
|
|
|
We ICE on the simple:
struct X { const X* x = this; };
constexpr const X& x = X{};
where store_init_value initializes 'x' with
&TARGET_EXPR <D.2768, {.x=(const struct X *) &<PLACEHOLDER_EXPR struct X>}>
but we must lifetime-extend via extend_ref_init_temps and we get
_ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>>;, (const struct X &) &_ZGR1x_;
Since 'x' was declared constexpr, we do cxx_constant_init and we hit
the preeval code added in r269003 while evaluating the INIT_EXPR:
_ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>>
but we have no ctx.ctor or ctx.object here so lookup_placeholder won't
find anything that could replace X and we ICE on
7861 /* A placeholder without a referent. We can get here when
7862 checking whether NSDMIs are noexcept, or in massage_init_elt;
7863 just say it's non-constant for now. */
7864 gcc_assert (ctx->quiet);
because cxx_constant_init means !ctx->quiet. It's not correct that
there isn't a referent. I think the following patch is a pretty
straightforward fix: pass the _ZGR var down to maybe_constant_init so
that it can replace the PLACEHOLDER_EXPR with _ZGR1x_.
The commented assert in the test doesn't pass: we complain that _ZGR1x_
isn't a constexpr variable because we don't implement DR2126 (PR101588).
PR c++/107079
gcc/cp/ChangeLog:
* call.cc (set_up_extended_ref_temp): Pass var to maybe_constant_init.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/constexpr-nsdmi2.C: New test.
|
|
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_allocate): Parse align
clause and check for restrictions.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_omp_allocate): Parse align
clause and check for restrictions.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/allocate-5.c: Extend for align clause.
|
|
For standard excess precision, like the C FE we parse floating
point constants as EXCESS_PRECISION_EXPR of promoted REAL_CST
rather than the nominal REAL_CST, and as the following testcase
shows the constants might need mangling.
The following patch mangles those as fold_convert of the REAL_CST
to EXCESS_PRECISION_EXPR type, i.e. how they were mangled before.
I'm not really sure EXCESS_PRECISION_EXPR can appear elsewhere
in expressions that would need mangling, tried various testcases
but haven't managed to come up with one. If that is possible,
we'd keep ICEing on it without/with this patch, and the big question
is how to mangle those; they could be mangled as casts from the
promoted type back to nominal, but then in the mangled expressions
one could see the effects of excess precision. Until we have
a reproducer, that is just theoretical though.
2023-02-09 Jakub Jelinek <jakub@redhat.com>
PR c++/108698
* mangle.cc (write_expression, write_template_arg): Handle
EXCESS_PRECISION_EXPR with REAL_CST operand as
write_template_arg_literal on fold_convert of the REAL_CST
to EXCESS_PRECISION_EXPR type.
* g++.dg/cpp0x/pr108698.C: New test.
|
|
|
|
After r13-5684-g59e0376f607805 the (pruned) callee of a non-dependent
CALL_EXPR is a bare FUNCTION_DECL rather than ADDR_EXPR of FUNCTION_DECL.
This innocent change revealed that cp_tree_equal doesn't first check
dependence of a CALL_EXPR before treating a FUNCTION_DECL callee as a
dependent name, which leads to us incorrectly accepting the first two
testcases below and rejecting the third:
* In the first testcase, cp_tree_equal incorrectly returns true for
the two non-dependent CALL_EXPRs f(0) and f(0) (whose CALL_EXPR_FN
are different FUNCTION_DECLs) which causes us to treat #2 as a
redeclaration of #1.
* Same issue in the second testcase, for f<int*>() and f<char>().
* In the third testcase, cp_tree_equal incorrectly returns true for
f<int>() and f<void(*)(int)>() which causes us to conflate the two
dependent specializations A<decltype(f<int>()(U()))> and
A<decltype(f<void(*)(int)>()(U()))>.
This patch fixes this by making called_fns_equal treat two callees as
dependent names only if the overall CALL_EXPRs are dependent, via a new
convenience function call_expr_dependent_name that is like dependent_name
but also checks dependence of the overall CALL_EXPR.
PR c++/107461
gcc/cp/ChangeLog:
* cp-tree.h (call_expr_dependent_name): Declare.
* pt.cc (iterative_hash_template_arg) <case CALL_EXPR>: Use
call_expr_dependent_name instead of dependent_name.
* tree.cc (call_expr_dependent_name): Define.
(called_fns_equal): Adjust to take two CALL_EXPRs instead of
CALL_EXPR_FNs thereof. Use call_expr_dependent_name instead
of dependent_name.
(cp_tree_equal) <case CALL_EXPR>: Adjust call to called_fns_equal.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/overload5.C: New test.
* g++.dg/cpp0x/overload5a.C: New test.
* g++.dg/cpp0x/overload6.C: New test.
|