re PR c++/52748 ([C++11] N3276 changes to decltype)
PR c++/52748 * parser.c (complain_flags): New. (cp_parser_postfix_expression): Use it. (cp_parser_unary_expression): Likewise. (cp_parser_binary_expression): Likewise. (cp_parser_assignment_expression): Likewise. (cp_parser_expression): Likewise. (cp_parser_postfix_open_square_expression): Take decltype_p. (cp_parser_builtin_offsetof): Adjust. (cp_convert_range_for): Pass complain to finish_unary_op_expr. * semantics.c (finish_unary_op_expr): Add complain parm. From-SVN: r197826
This commit is contained in:
parent
43a8d6ccf2
commit
e59baf0517
|
@ -1,3 +1,17 @@
|
||||||
|
2013-04-11 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/52748
|
||||||
|
* parser.c (complain_flags): New.
|
||||||
|
(cp_parser_postfix_expression): Use it.
|
||||||
|
(cp_parser_unary_expression): Likewise.
|
||||||
|
(cp_parser_binary_expression): Likewise.
|
||||||
|
(cp_parser_assignment_expression): Likewise.
|
||||||
|
(cp_parser_expression): Likewise.
|
||||||
|
(cp_parser_postfix_open_square_expression): Take decltype_p.
|
||||||
|
(cp_parser_builtin_offsetof): Adjust.
|
||||||
|
(cp_convert_range_for): Pass complain to finish_unary_op_expr.
|
||||||
|
* semantics.c (finish_unary_op_expr): Add complain parm.
|
||||||
|
|
||||||
2013-04-11 Jakub Jelinek <jakub@redhat.com>
|
2013-04-11 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/56895
|
PR c++/56895
|
||||||
|
|
|
@ -5241,7 +5241,7 @@ extern void maybe_make_one_only (tree);
|
||||||
extern bool vague_linkage_p (tree);
|
extern bool vague_linkage_p (tree);
|
||||||
extern void grokclassfn (tree, tree,
|
extern void grokclassfn (tree, tree,
|
||||||
enum overload_flags);
|
enum overload_flags);
|
||||||
extern tree grok_array_decl (location_t, tree, tree);
|
extern tree grok_array_decl (location_t, tree, tree, bool);
|
||||||
extern tree delete_sanity (tree, tree, bool, int, tsubst_flags_t);
|
extern tree delete_sanity (tree, tree, bool, int, tsubst_flags_t);
|
||||||
extern tree check_classfn (tree, tree, tree);
|
extern tree check_classfn (tree, tree, tree);
|
||||||
extern void check_member_template (tree);
|
extern void check_member_template (tree);
|
||||||
|
@ -5706,7 +5706,8 @@ extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool,
|
||||||
extern tree finish_increment_expr (tree, enum tree_code);
|
extern tree finish_increment_expr (tree, enum tree_code);
|
||||||
extern tree finish_this_expr (void);
|
extern tree finish_this_expr (void);
|
||||||
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
|
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
|
||||||
extern tree finish_unary_op_expr (location_t, enum tree_code, tree);
|
extern tree finish_unary_op_expr (location_t, enum tree_code, tree,
|
||||||
|
tsubst_flags_t);
|
||||||
extern tree finish_compound_literal (tree, tree, tsubst_flags_t);
|
extern tree finish_compound_literal (tree, tree, tsubst_flags_t);
|
||||||
extern tree finish_fname (tree);
|
extern tree finish_fname (tree);
|
||||||
extern void finish_translation_unit (void);
|
extern void finish_translation_unit (void);
|
||||||
|
|
|
@ -335,10 +335,11 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an ARRAY_REF, checking for the user doing things backwards
|
/* Create an ARRAY_REF, checking for the user doing things backwards
|
||||||
along the way. */
|
along the way. DECLTYPE_P is for N3276, as in the parser. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
grok_array_decl (location_t loc, tree array_expr, tree index_exp)
|
grok_array_decl (location_t loc, tree array_expr, tree index_exp,
|
||||||
|
bool decltype_p)
|
||||||
{
|
{
|
||||||
tree type;
|
tree type;
|
||||||
tree expr;
|
tree expr;
|
||||||
|
@ -364,8 +365,13 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp)
|
||||||
|
|
||||||
/* If they have an `operator[]', use that. */
|
/* If they have an `operator[]', use that. */
|
||||||
if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
|
if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
|
||||||
expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr, index_exp,
|
{
|
||||||
NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
|
tsubst_flags_t complain = tf_warning_or_error;
|
||||||
|
if (decltype_p)
|
||||||
|
complain |= tf_decltype;
|
||||||
|
expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr,
|
||||||
|
index_exp, NULL_TREE, /*overload=*/NULL, complain);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree p1, p2, i1, i2;
|
tree p1, p2, i1, i2;
|
||||||
|
|
|
@ -1852,7 +1852,7 @@ static tree cp_parser_qualifying_entity
|
||||||
static tree cp_parser_postfix_expression
|
static tree cp_parser_postfix_expression
|
||||||
(cp_parser *, bool, bool, bool, bool, cp_id_kind *);
|
(cp_parser *, bool, bool, bool, bool, cp_id_kind *);
|
||||||
static tree cp_parser_postfix_open_square_expression
|
static tree cp_parser_postfix_open_square_expression
|
||||||
(cp_parser *, tree, bool);
|
(cp_parser *, tree, bool, bool);
|
||||||
static tree cp_parser_postfix_dot_deref_expression
|
static tree cp_parser_postfix_dot_deref_expression
|
||||||
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
|
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
|
||||||
static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
|
static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
|
||||||
|
@ -3891,6 +3891,18 @@ cp_parser_translation_unit (cp_parser* parser)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the appropriate tsubst flags for parsing, possibly in N3276
|
||||||
|
decltype context. */
|
||||||
|
|
||||||
|
static inline tsubst_flags_t
|
||||||
|
complain_flags (bool decltype_p)
|
||||||
|
{
|
||||||
|
tsubst_flags_t complain = tf_warning_or_error;
|
||||||
|
if (decltype_p)
|
||||||
|
complain |= tf_decltype;
|
||||||
|
return complain;
|
||||||
|
}
|
||||||
|
|
||||||
/* Expressions [gram.expr] */
|
/* Expressions [gram.expr] */
|
||||||
|
|
||||||
/* Parse a primary-expression.
|
/* Parse a primary-expression.
|
||||||
|
@ -5726,7 +5738,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
postfix_expression
|
postfix_expression
|
||||||
= cp_parser_postfix_open_square_expression (parser,
|
= cp_parser_postfix_open_square_expression (parser,
|
||||||
postfix_expression,
|
postfix_expression,
|
||||||
false);
|
false,
|
||||||
|
decltype_p);
|
||||||
idk = CP_ID_KIND_NONE;
|
idk = CP_ID_KIND_NONE;
|
||||||
is_member_access = false;
|
is_member_access = false;
|
||||||
break;
|
break;
|
||||||
|
@ -5738,12 +5751,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
bool is_builtin_constant_p;
|
bool is_builtin_constant_p;
|
||||||
bool saved_integral_constant_expression_p = false;
|
bool saved_integral_constant_expression_p = false;
|
||||||
bool saved_non_integral_constant_expression_p = false;
|
bool saved_non_integral_constant_expression_p = false;
|
||||||
int complain = tf_warning_or_error;
|
tsubst_flags_t complain = complain_flags (decltype_p);
|
||||||
vec<tree, va_gc> *args;
|
vec<tree, va_gc> *args;
|
||||||
|
|
||||||
if (decltype_p)
|
|
||||||
complain |= tf_decltype;
|
|
||||||
|
|
||||||
is_member_access = false;
|
is_member_access = false;
|
||||||
|
|
||||||
is_builtin_constant_p
|
is_builtin_constant_p
|
||||||
|
@ -5972,7 +5982,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
static tree
|
static tree
|
||||||
cp_parser_postfix_open_square_expression (cp_parser *parser,
|
cp_parser_postfix_open_square_expression (cp_parser *parser,
|
||||||
tree postfix_expression,
|
tree postfix_expression,
|
||||||
bool for_offsetof)
|
bool for_offsetof,
|
||||||
|
bool decltype_p)
|
||||||
{
|
{
|
||||||
tree index;
|
tree index;
|
||||||
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
|
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
|
||||||
|
@ -6006,7 +6017,8 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
|
||||||
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
|
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
|
||||||
|
|
||||||
/* Build the ARRAY_REF. */
|
/* Build the ARRAY_REF. */
|
||||||
postfix_expression = grok_array_decl (loc, postfix_expression, index);
|
postfix_expression = grok_array_decl (loc, postfix_expression,
|
||||||
|
index, decltype_p);
|
||||||
|
|
||||||
/* When not doing offsetof, array references are not permitted in
|
/* When not doing offsetof, array references are not permitted in
|
||||||
constant-expressions. */
|
constant-expressions. */
|
||||||
|
@ -6702,6 +6714,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
tree expression = error_mark_node;
|
tree expression = error_mark_node;
|
||||||
non_integral_constant non_constant_p = NIC_NONE;
|
non_integral_constant non_constant_p = NIC_NONE;
|
||||||
location_t loc = token->location;
|
location_t loc = token->location;
|
||||||
|
tsubst_flags_t complain = complain_flags (decltype_p);
|
||||||
|
|
||||||
/* Consume the operator token. */
|
/* Consume the operator token. */
|
||||||
token = cp_lexer_consume_token (parser->lexer);
|
token = cp_lexer_consume_token (parser->lexer);
|
||||||
|
@ -6719,7 +6732,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
non_constant_p = NIC_STAR;
|
non_constant_p = NIC_STAR;
|
||||||
expression = build_x_indirect_ref (loc, cast_expression,
|
expression = build_x_indirect_ref (loc, cast_expression,
|
||||||
RO_UNARY_STAR,
|
RO_UNARY_STAR,
|
||||||
tf_warning_or_error);
|
complain);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADDR_EXPR:
|
case ADDR_EXPR:
|
||||||
|
@ -6728,7 +6741,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
case BIT_NOT_EXPR:
|
case BIT_NOT_EXPR:
|
||||||
expression = build_x_unary_op (loc, unary_operator,
|
expression = build_x_unary_op (loc, unary_operator,
|
||||||
cast_expression,
|
cast_expression,
|
||||||
tf_warning_or_error);
|
complain);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREINCREMENT_EXPR:
|
case PREINCREMENT_EXPR:
|
||||||
|
@ -6740,7 +6753,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||||
case NEGATE_EXPR:
|
case NEGATE_EXPR:
|
||||||
case TRUTH_NOT_EXPR:
|
case TRUTH_NOT_EXPR:
|
||||||
expression = finish_unary_op_expr (loc, unary_operator,
|
expression = finish_unary_op_expr (loc, unary_operator,
|
||||||
cast_expression);
|
cast_expression, complain);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -7567,7 +7580,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
|
||||||
current.lhs = build_x_binary_op (current.loc, current.tree_type,
|
current.lhs = build_x_binary_op (current.loc, current.tree_type,
|
||||||
current.lhs, current.lhs_type,
|
current.lhs, current.lhs_type,
|
||||||
rhs, rhs_type, &overload,
|
rhs, rhs_type, &overload,
|
||||||
tf_warning_or_error);
|
complain_flags (decltype_p));
|
||||||
current.lhs_type = current.tree_type;
|
current.lhs_type = current.tree_type;
|
||||||
if (EXPR_P (current.lhs))
|
if (EXPR_P (current.lhs))
|
||||||
SET_EXPR_LOCATION (current.lhs, current.loc);
|
SET_EXPR_LOCATION (current.lhs, current.loc);
|
||||||
|
@ -7722,7 +7735,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
|
||||||
expr = build_x_modify_expr (loc, expr,
|
expr = build_x_modify_expr (loc, expr,
|
||||||
assignment_operator,
|
assignment_operator,
|
||||||
rhs,
|
rhs,
|
||||||
tf_warning_or_error);
|
complain_flags (decltype_p));
|
||||||
input_location = saved_input_location;
|
input_location = saved_input_location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7868,7 +7881,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p, bool decltype_p,
|
||||||
else
|
else
|
||||||
expression = build_x_compound_expr (loc, expression,
|
expression = build_x_compound_expr (loc, expression,
|
||||||
assignment_expression,
|
assignment_expression,
|
||||||
tf_warning_or_error);
|
complain_flags (decltype_p));
|
||||||
/* If the next token is not a comma, then we are done with the
|
/* If the next token is not a comma, then we are done with the
|
||||||
expression. */
|
expression. */
|
||||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
|
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
|
||||||
|
@ -8019,12 +8032,14 @@ cp_parser_builtin_offsetof (cp_parser *parser)
|
||||||
{
|
{
|
||||||
case CPP_OPEN_SQUARE:
|
case CPP_OPEN_SQUARE:
|
||||||
/* offsetof-member-designator "[" expression "]" */
|
/* offsetof-member-designator "[" expression "]" */
|
||||||
expr = cp_parser_postfix_open_square_expression (parser, expr, true);
|
expr = cp_parser_postfix_open_square_expression (parser, expr,
|
||||||
|
true, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPP_DEREF:
|
case CPP_DEREF:
|
||||||
/* offsetof-member-designator "->" identifier */
|
/* offsetof-member-designator "->" identifier */
|
||||||
expr = grok_array_decl (token->location, expr, integer_zero_node);
|
expr = grok_array_decl (token->location, expr,
|
||||||
|
integer_zero_node, false);
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
|
||||||
case CPP_DOT:
|
case CPP_DOT:
|
||||||
|
@ -9766,7 +9781,8 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
|
||||||
|
|
||||||
/* The new increment expression. */
|
/* The new increment expression. */
|
||||||
expression = finish_unary_op_expr (input_location,
|
expression = finish_unary_op_expr (input_location,
|
||||||
PREINCREMENT_EXPR, begin);
|
PREINCREMENT_EXPR, begin,
|
||||||
|
tf_warning_or_error);
|
||||||
finish_for_expr (expression, statement);
|
finish_for_expr (expression, statement);
|
||||||
|
|
||||||
/* The declaration is initialized with *__begin inside the loop body. */
|
/* The declaration is initialized with *__begin inside the loop body. */
|
||||||
|
|
|
@ -2408,10 +2408,12 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
|
||||||
/* Finish an expression of the form CODE EXPR. */
|
/* Finish an expression of the form CODE EXPR. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
finish_unary_op_expr (location_t loc, enum tree_code code, tree expr)
|
finish_unary_op_expr (location_t loc, enum tree_code code, tree expr,
|
||||||
|
tsubst_flags_t complain)
|
||||||
{
|
{
|
||||||
tree result = build_x_unary_op (loc, code, expr, tf_warning_or_error);
|
tree result = build_x_unary_op (loc, code, expr, complain);
|
||||||
if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
|
if ((complain & tf_warning)
|
||||||
|
&& TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
|
||||||
overflow_warning (input_location, result);
|
overflow_warning (input_location, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Testcase for N3276 and operator overloading
|
||||||
|
// { dg-require-effective-target c++11 }
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
struct B {
|
||||||
|
A operator()(int);
|
||||||
|
A operator[](int);
|
||||||
|
A operator=(int);
|
||||||
|
A operator+=(int);
|
||||||
|
A operator-=(int);
|
||||||
|
A operator*=(int);
|
||||||
|
A operator/=(int);
|
||||||
|
A operator^=(int);
|
||||||
|
A operator&=(int);
|
||||||
|
A operator|=(int);
|
||||||
|
A operator<<=(int);
|
||||||
|
A operator>>=(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
A operator-(B);
|
||||||
|
A operator+(B);
|
||||||
|
A operator*(B);
|
||||||
|
A operator&(B);
|
||||||
|
A operator!(B);
|
||||||
|
A operator~(B);
|
||||||
|
A operator++(B);
|
||||||
|
A operator--(B);
|
||||||
|
|
||||||
|
A operator+(B,B);
|
||||||
|
A operator-(B,B);
|
||||||
|
A operator*(B,B);
|
||||||
|
A operator/(B,B);
|
||||||
|
A operator%(B,B);
|
||||||
|
A operator^(B,B);
|
||||||
|
A operator&(B,B);
|
||||||
|
A operator|(B,B);
|
||||||
|
A operator<(B,B);
|
||||||
|
A operator>(B,B);
|
||||||
|
A operator,(B,B);
|
||||||
|
A operator<<(B,B);
|
||||||
|
A operator>>(B,B);
|
||||||
|
A operator==(B,B);
|
||||||
|
A operator->*(B,B);
|
||||||
|
|
||||||
|
#define TRY(E) static_cast<decltype(E)*>(0)
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
B b;
|
||||||
|
TRY(b(0));
|
||||||
|
TRY(b[0]);
|
||||||
|
TRY(b=0);
|
||||||
|
TRY(b+=0);
|
||||||
|
TRY(b-=0);
|
||||||
|
TRY(b*=0);
|
||||||
|
TRY(b/=0);
|
||||||
|
TRY(b^=0);
|
||||||
|
TRY(b&=0);
|
||||||
|
TRY(b|=0);
|
||||||
|
TRY(b<<=0);
|
||||||
|
TRY(b>>=0);
|
||||||
|
|
||||||
|
TRY(-b);
|
||||||
|
TRY(+b);
|
||||||
|
TRY(*b);
|
||||||
|
TRY(&b);
|
||||||
|
TRY(!b);
|
||||||
|
TRY(~b);
|
||||||
|
TRY(++b);
|
||||||
|
TRY(--b);
|
||||||
|
|
||||||
|
TRY(b+b);
|
||||||
|
TRY(b-b);
|
||||||
|
TRY(b*b);
|
||||||
|
TRY(b/b);
|
||||||
|
TRY(b%b);
|
||||||
|
TRY(b^b);
|
||||||
|
TRY(b&b);
|
||||||
|
TRY(b|b);
|
||||||
|
TRY(b>b);
|
||||||
|
TRY(b<b);
|
||||||
|
TRY((b,b));
|
||||||
|
TRY(b<<b);
|
||||||
|
TRY(b>>b);
|
||||||
|
TRY(b==b);
|
||||||
|
TRY(b->*b);
|
||||||
|
}
|
Loading…
Reference in New Issue