rhs = TREE_TYPE (rhs); /* Pointer type. */
/* We could be called while processing a template and RHS could be
a functor. In that case it's a class, not a pointer. */
- if (!POINTER_TYPE_P (rhs))
+ if (!rhs || !POINTER_TYPE_P (rhs))
return NULL_TREE;
rhs = TREE_TYPE (rhs); /* Function type. */
rhstype = TREE_TYPE (rhs);
rhs = BASELINK_FUNCTIONS (rhs);
}
- /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
- deduce any type information. */
- if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
- {
- if (complain & tf_error)
- error ("not enough type information");
- return error_mark_node;
- }
-
/* There are only a few kinds of expressions that may have a type
dependent on overload resolution. */
gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
case MODOP_EXPR:
/* GCC internal stuff. */
case VA_ARG_EXPR:
- case NON_DEPENDENT_EXPR:
case BASELINK:
case OFFSET_REF:
if (!ctx->quiet)
case BIND_EXPR:
return RECUR (BIND_EXPR_BODY (t), want_rval);
- case NON_DEPENDENT_EXPR:
- /* Treat NON_DEPENDENT_EXPR as non-constant: it's not handled by
- constexpr evaluation or tsubst, so fold_non_dependent_expr can't
- do anything useful with it. And we shouldn't see it in a context
- where a constant expression is strictly required, hence the assert. */
- gcc_checking_assert (!(flags & tf_error));
- return false;
-
case CLEANUP_POINT_EXPR:
case MUST_NOT_THROW_EXPR:
case TRY_CATCH_EXPR:
location_t loc = EXPR_LOCATION (arg);
/* We expect alignof expressions in templates. */
- if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
- && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
+ if (TREE_CODE (arg) == ALIGNOF_EXPR)
;
else if (!TREE_CONSTANT (arg))
{
MARK_TS_EXP (MUST_NOT_THROW_EXPR);
MARK_TS_EXP (NEW_EXPR);
MARK_TS_EXP (NOEXCEPT_EXPR);
- MARK_TS_EXP (NON_DEPENDENT_EXPR);
MARK_TS_EXP (OFFSETOF_EXPR);
MARK_TS_EXP (OFFSET_REF);
MARK_TS_EXP (PSEUDO_DTOR_EXPR);
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
DEFTREECODE (SPACESHIP_EXPR, "spaceship_expr", tcc_expression, 2)
-/* A placeholder for an expression that is not type-dependent, but
- does occur in a template. When an expression that is not
- type-dependent appears in a larger expression, we must compute the
- type of that larger expression. That computation would normally
- modify the original expression, which would change the mangling of
- that expression if it appeared in a template argument list. In
- that situation, we create a NON_DEPENDENT_EXPR to take the place of
- the original expression. The expression is the only operand -- it
- is only needed for diagnostics. */
-DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
-
/* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
extern bool dependent_omp_for_p (tree, tree, tree, tree);
extern tree resolve_typename_type (tree, bool);
extern tree template_for_substitution (tree);
-extern tree build_non_dependent_expr (tree);
+inline tree build_non_dependent_expr (tree t) { return t; } // XXX remove
extern void make_args_non_dependent (vec<tree, va_gc> *);
extern bool reregister_specialization (tree, tree, tree);
extern tree instantiate_non_dependent_expr (tree, tsubst_flags_t = tf_error);
call = TARGET_EXPR_INITIAL (expr);
location_t loc = cp_expr_loc_or_input_loc (call);
tree callee = cp_get_callee (call);
- if (!callee)
+ if (!callee || !TREE_TYPE (callee))
return;
tree type = TREE_TYPE (callee);
type = TYPE_PTRMEMFUNC_FN_TYPE (type);
if (INDIRECT_TYPE_P (type))
type = TREE_TYPE (type);
+ if (!FUNC_OR_METHOD_TYPE_P (type))
+ return;
tree rettype = TREE_TYPE (type);
tree fn = cp_get_fndecl_from_callee (callee);
assignment_expression (t);
break;
- case NON_DEPENDENT_EXPR:
case MUST_NOT_THROW_EXPR:
expression (TREE_OPERAND (t, 0));
break;
dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
break;
- case NON_DEPENDENT_EXPR:
- dump_expr (pp, t, flags);
- break;
-
case TEMPLATE_TYPE_PARM:
if (flags & TFF_DECL_SPECIFIERS)
pp->declaration (t);
pp_cxx_right_paren (pp);
break;
- case NON_DEPENDENT_EXPR:
- dump_expr (pp, TREE_OPERAND (t, 0), flags);
- break;
-
case ARGUMENT_PACK_SELECT:
dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
break;
}
break;
case COMPONENT_REF:
- case NON_DEPENDENT_EXPR:
recurse_op[0] = true;
break;
case COMPOUND_EXPR:
case ADDR_EXPR:
case INDIRECT_REF:
case FLOAT_EXPR:
- case NON_DEPENDENT_EXPR:
case VIEW_CONVERT_EXPR:
mark_exp_read (TREE_OPERAND (exp, 0));
break;
return result;
}
-/* EXPR is an expression which is not type-dependent. Return a proxy
- for EXPR that can be used to compute the types of larger
- expressions containing EXPR. */
-
-tree
-build_non_dependent_expr (tree expr)
-{
- tree orig_expr = expr;
- tree inner_expr;
-
- /* When checking, try to get a constant value for all non-dependent
- expressions in order to expose bugs in *_dependent_expression_p
- and constexpr. This can affect code generation, see PR70704, so
- only do this for -fchecking=2. */
- if (flag_checking > 1
- && cxx_dialect >= cxx11
- /* Don't do this during nsdmi parsing as it can lead to
- unexpected recursive instantiations. */
- && !parsing_nsdmi ()
- /* Don't do this during concept processing either and for
- the same reason. */
- && !processing_constraint_expression_p ())
- fold_non_dependent_expr (expr, tf_none);
-
- STRIP_ANY_LOCATION_WRAPPER (expr);
-
- /* Preserve OVERLOADs; the functions must be available to resolve
- types. */
- inner_expr = expr;
- if (TREE_CODE (inner_expr) == STMT_EXPR)
- inner_expr = stmt_expr_value_expr (inner_expr);
- if (TREE_CODE (inner_expr) == ADDR_EXPR)
- inner_expr = TREE_OPERAND (inner_expr, 0);
- if (TREE_CODE (inner_expr) == COMPONENT_REF)
- inner_expr = TREE_OPERAND (inner_expr, 1);
- if (is_overloaded_fn (inner_expr)
- || TREE_CODE (inner_expr) == OFFSET_REF)
- return orig_expr;
- /* There is no need to return a proxy for a variable, parameter
- or enumerator. */
- if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL
- || TREE_CODE (expr) == CONST_DECL)
- return orig_expr;
- /* Preserve string constants; conversions from string constants to
- "char *" are allowed, even though normally a "const char *"
- cannot be used to initialize a "char *". */
- if (TREE_CODE (expr) == STRING_CST)
- return orig_expr;
- /* Preserve void and arithmetic constants, as an optimization -- there is no
- reason to create a new node. */
- if (TREE_CODE (expr) == VOID_CST
- || TREE_CODE (expr) == INTEGER_CST
- || TREE_CODE (expr) == REAL_CST)
- return orig_expr;
- /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
- There is at least one place where we want to know that a
- particular expression is a throw-expression: when checking a ?:
- expression, there are special rules if the second or third
- argument is a throw-expression. */
- if (TREE_CODE (expr) == THROW_EXPR)
- return orig_expr;
-
- /* Don't wrap an initializer list, we need to be able to look inside. */
- if (BRACE_ENCLOSED_INITIALIZER_P (expr))
- return orig_expr;
-
- /* Don't wrap a dummy object, we need to be able to test for it. */
- if (is_dummy_object (expr))
- return orig_expr;
-
- if (TREE_CODE (expr) == COND_EXPR)
- return build3 (COND_EXPR,
- TREE_TYPE (expr),
- build_non_dependent_expr (TREE_OPERAND (expr, 0)),
- (TREE_OPERAND (expr, 1)
- ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
- : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
- build_non_dependent_expr (TREE_OPERAND (expr, 2)));
- if (TREE_CODE (expr) == COMPOUND_EXPR)
- return build2 (COMPOUND_EXPR,
- TREE_TYPE (expr),
- TREE_OPERAND (expr, 0),
- build_non_dependent_expr (TREE_OPERAND (expr, 1)));
-
- /* If the type is unknown, it can't really be non-dependent */
- gcc_assert (TREE_TYPE (expr) != unknown_type_node);
-
- /* Otherwise, build a NON_DEPENDENT_EXPR. */
- return build1_loc (EXPR_LOCATION (orig_expr), NON_DEPENDENT_EXPR,
- TREE_TYPE (expr), expr);
-}
-
/* ARGS is a vector of expressions as arguments to a function call.
Replace the arguments with equivalent non-dependent expressions.
This modifies ARGS in place. */
its argument unmodified and we assign it to a const_tree. */
return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
- case NON_DEPENDENT_EXPR:
case PAREN_EXPR:
return lvalue_kind (TREE_OPERAND (ref, 0));
STRIP_ANY_LOCATION_WRAPPER (ref);
switch (TREE_CODE (ref))
{
- case NON_DEPENDENT_EXPR:
- /* We aren't actually evaluating this. */
- return ref;
-
/* We need to treat specially anything stabilize_reference doesn't
handle specifically. */
case VAR_DECL:
|| warning_suppressed_p (op, OPT_Waddress))
return;
- if (TREE_CODE (op) == NON_DEPENDENT_EXPR)
- op = TREE_OPERAND (op, 0);
-
tree cop = fold_for_warn (op);
if (TREE_CODE (cop) == NON_LVALUE_EXPR)
type0 = TREE_TYPE (type0);
if (!TYPE_P (type1))
type1 = TREE_TYPE (type1);
- if (INDIRECT_TYPE_P (type0) && same_type_p (TREE_TYPE (type0), type1))
+ if (type0
+ && INDIRECT_TYPE_P (type0)
+ && same_type_p (TREE_TYPE (type0), type1))
{
if (!(TREE_CODE (first_arg) == PARM_DECL
&& DECL_ARRAY_PARAMETER_P (first_arg)
"first %<sizeof%> operand was declared here");
}
}
- else if (TREE_CODE (type0) == ARRAY_TYPE
+ else if (!dependent_type_p (type0)
+ && !dependent_type_p (type1)
+ && TREE_CODE (type0) == ARRAY_TYPE
&& !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
/* Set by finish_parenthesized_expr. */
&& !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
complain);
if (arg != error_mark_node)
{
+ if (processing_template_decl)
+ return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
val = invert_truthvalue_loc (location, arg);
if (obvalue_p (val))
val = non_lvalue_loc (location, val);
template<typename U>
- requires C1<U>() // { dg-error "cannot be used as a function" }
+ requires C1<U>() // { dg-error "cannot call a concept" }
void f1(U) { }
template<typename U>