C ObjC C++ ObjC++ Warning Var(warn_varargs) Init(1)
Warn about questionable usage of the macros used to retrieve variable arguments.
+Wvexing-parse
+C++ ObjC++ Warning Var(warn_vexing_parse) Init(1)
+Warn about the most vexing parse syntactic ambiguity.
+
Wvla
C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
Warn if a variable length array is used.
CPTI_CLASS_TYPE,
CPTI_UNKNOWN_TYPE,
CPTI_INIT_LIST_TYPE,
+ CPTI_EXPLICIT_VOID_LIST,
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
CPTI_STD,
#define class_type_node cp_global_trees[CPTI_CLASS_TYPE]
#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE]
#define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE]
+#define explicit_void_list_node cp_global_trees[CPTI_EXPLICIT_VOID_LIST]
#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
#define std_node cp_global_trees[CPTI_STD]
ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
ABI_TAG_IMPLICIT (in the TREE_LIST for the argument of abi_tag)
LAMBDA_CAPTURE_EXPLICIT_P (in a TREE_LIST in LAMBDA_EXPR_CAPTURE_LIST)
+ PARENTHESIZED_LIST_P (in the TREE_LIST for a parameter-declaration-list)
CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
was inherited from a template parameter, not explicitly indicated. */
#define ABI_TAG_IMPLICIT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+/* In a TREE_LIST for a parameter-declaration-list, indicates that all the
+ parameters in the list have declarators enclosed in (). */
+#define PARENTHESIZED_LIST_P(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
/* Non zero if this is a using decl for a dependent scope. */
#define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE))
tree late_return_type;
/* The trailing requires-clause, if any. */
tree requires_clause;
+ location_t parens_loc;
} function;
/* For arrays. */
struct {
init_list_type_node = make_node (LANG_TYPE);
record_unknown_type (init_list_type_node, "init list");
+ /* Used when parsing to distinguish parameter-lists () and (void). */
+ explicit_void_list_node = build_void_list_node ();
+
{
/* Make sure we get a unique function type, so we can give
its pointer type a name. (This wins for gdb.) */
tree init = TREE_PURPOSE (parm);
tree decl = TREE_VALUE (parm);
- if (parm == void_list_node)
+ if (parm == void_list_node || parm == explicit_void_list_node)
break;
if (! decl || TREE_TYPE (decl) == error_mark_node)
VAR_DECLs or FUNCTION_DECLs) should do that directly. */
static cp_declarator *make_call_declarator
- (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, tree, tree, tree, tree);
+ (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier,
+ tree, tree, tree, tree, location_t);
static cp_declarator *make_array_declarator
(cp_declarator *, tree);
static cp_declarator *make_pointer_declarator
tree tx_qualifier,
tree exception_specification,
tree late_return_type,
- tree requires_clause)
+ tree requires_clause,
+ location_t parens_loc)
{
cp_declarator *declarator;
declarator->u.function.exception_specification = exception_specification;
declarator->u.function.late_return_type = late_return_type;
declarator->u.function.requires_clause = requires_clause;
+ declarator->u.function.parens_loc = parens_loc;
if (target)
{
declarator->id_loc = target->id_loc;
tx_qual,
exception_spec,
return_type,
- trailing_requires_clause);
+ trailing_requires_clause,
+ UNKNOWN_LOCATION);
declarator->std_attributes = std_attrs;
fco = grokmethod (&return_type_specs,
return type;
}
+/* Warn about the most vexing parse syntactic ambiguity, i.e., warn when
+ a construct looks like a variable definition but is actually a function
+ declaration. DECL_SPECIFIERS is the decl-specifier-seq and DECLARATOR
+ is the declarator for this function declaration. */
+
+static void
+warn_about_ambiguous_parse (const cp_decl_specifier_seq *decl_specifiers,
+ const cp_declarator *declarator)
+{
+ /* Only warn if we are declaring a function at block scope. */
+ if (!at_function_scope_p ())
+ return;
+
+ /* And only if there is no storage class specified. */
+ if (decl_specifiers->storage_class != sc_none
+ || decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
+ return;
+
+ if (declarator->kind != cdk_function
+ || !declarator->declarator
+ || declarator->declarator->kind != cdk_id
+ || !identifier_p (get_unqualified_id
+ (const_cast<cp_declarator *>(declarator))))
+ return;
+
+ /* Don't warn when the whole declarator (not just the declarator-id!)
+ was parenthesized. That is, don't warn for int(n()) but do warn
+ for int(f)(). */
+ if (declarator->parenthesized != UNKNOWN_LOCATION)
+ return;
+
+ tree type = decl_specifiers->type;
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+
+ /* If the return type is void there is no ambiguity. */
+ if (same_type_p (type, void_type_node))
+ return;
+
+ auto_diagnostic_group d;
+ location_t loc = declarator->u.function.parens_loc;
+ tree params = declarator->u.function.parameters;
+ const bool has_list_ctor_p = CLASS_TYPE_P (type) && TYPE_HAS_LIST_CTOR (type);
+
+ /* The T t() case. */
+ if (params == void_list_node)
+ {
+ if (warning_at (loc, OPT_Wvexing_parse,
+ "empty parentheses were disambiguated as a function "
+ "declaration"))
+ {
+ /* () means value-initialization (C++03 and up); {} (C++11 and up)
+ means value-initialization or aggregate-initialization, nothing
+ means default-initialization. We can only suggest removing the
+ parentheses/adding {} if T has a default constructor. */
+ if (!CLASS_TYPE_P (type) || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
+ {
+ gcc_rich_location iloc (loc);
+ iloc.add_fixit_remove ();
+ inform (&iloc, "remove parentheses to default-initialize "
+ "a variable");
+ if (cxx_dialect >= cxx11 && !has_list_ctor_p)
+ {
+ if (CP_AGGREGATE_TYPE_P (type))
+ inform (loc, "or replace parentheses with braces to "
+ "aggregate-initialize a variable");
+ else
+ inform (loc, "or replace parentheses with braces to "
+ "value-initialize a variable");
+ }
+ }
+ }
+ return;
+ }
+
+ /* If we had (...) or the parameter-list wasn't parenthesized,
+ we're done. */
+ if (params == NULL_TREE || !PARENTHESIZED_LIST_P (params))
+ return;
+
+ /* The T t(X()) case. */
+ if (list_length (params) == 2)
+ {
+ if (warning_at (loc, OPT_Wvexing_parse,
+ "parentheses were disambiguated as a function "
+ "declaration"))
+ {
+ gcc_rich_location iloc (loc);
+ /* {}-initialization means that we can use an initializer-list
+ constructor if no default constructor is available, so don't
+ suggest using {} for classes that have an initializer_list
+ constructor. */
+ if (cxx_dialect >= cxx11 && !has_list_ctor_p)
+ {
+ iloc.add_fixit_replace (get_start (loc), "{");
+ iloc.add_fixit_replace (get_finish (loc), "}");
+ inform (&iloc, "replace parentheses with braces to declare a "
+ "variable");
+ }
+ else
+ {
+ iloc.add_fixit_insert_after (get_start (loc), "(");
+ iloc.add_fixit_insert_before (get_finish (loc), ")");
+ inform (&iloc, "add parentheses to declare a variable");
+ }
+ }
+ }
+ /* The T t(X(), X()) case. */
+ else if (warning_at (loc, OPT_Wvexing_parse,
+ "parentheses were disambiguated as a function "
+ "declaration"))
+ {
+ gcc_rich_location iloc (loc);
+ if (cxx_dialect >= cxx11 && !has_list_ctor_p)
+ {
+ iloc.add_fixit_replace (get_start (loc), "{");
+ iloc.add_fixit_replace (get_finish (loc), "}");
+ inform (&iloc, "replace parentheses with braces to declare a "
+ "variable");
+ }
+ }
+}
+
/* Declarators [gram.dcl.decl] */
/* Parse an init-declarator.
}
}
+ if (!member_p && !cp_parser_error_occurred (parser))
+ warn_about_ambiguous_parse (decl_specifiers, declarator);
+
/* Check to see if the token indicates the start of a
function-definition. */
if (cp_parser_token_starts_function_definition_p (token))
/* If a ptr-operator was found, then this declarator was not
parenthesized. */
if (parenthesized_p)
- *parenthesized_p = true;
+ *parenthesized_p = false;
/* The dependent declarator is optional if we are parsing an
abstract-declarator. */
if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
cp_parser_parse_tentatively (parser);
/* Consume the `('. */
+ const location_t parens_start = token->location;
matching_parens parens;
parens.consume_open (parser);
if (first)
/* Parse the parameter-declaration-clause. */
params
= cp_parser_parameter_declaration_clause (parser, flags);
+ const location_t parens_end
+ = cp_lexer_peek_token (parser->lexer)->location;
/* Consume the `)'. */
parens.require_close (parser);
/* Parse the virt-specifier-seq. */
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
+ location_t parens_loc = make_location (parens_start,
+ parens_start,
+ parens_end);
/* Create the function-declarator. */
declarator = make_call_declarator (declarator,
params,
tx_qual,
exception_specification,
late_return,
- requires_clause);
+ requires_clause,
+ parens_loc);
declarator->std_attributes = attrs;
declarator->attributes = gnu_attrs;
/* Any subsequent parameter lists are to do with
/* Consume the `void' token. */
cp_lexer_consume_token (parser->lexer);
/* There are no parameters. */
- return void_list_node;
+ return explicit_void_list_node;
}
/* Parse the parameter-declaration-list. */
*tail = build_tree_list (parameter->default_argument, decl);
tail = &TREE_CHAIN (*tail);
+ /* If the parameters were parenthesized, it's the case of
+ T foo(X(x)) which looks like a variable definition but
+ is a function declaration. */
+ if (index == 1 || PARENTHESIZED_LIST_P (parameters))
+ PARENTHESIZED_LIST_P (parameters) = parenthesized_p;
+
/* Peek at the next token. */
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
|| cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
-Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo @gol
-Wsized-deallocation -Wsuggest-final-methods @gol
-Wsuggest-final-types -Wsuggest-override @gol
--Wno-terminate -Wuseless-cast -Wvirtual-inheritance @gol
+-Wno-terminate -Wuseless-cast -Wno-vexing-parse @gol
+-Wvirtual-inheritance @gol
-Wno-virtual-move-assign -Wvolatile -Wzero-as-null-pointer-constant}
@item Objective-C and Objective-C++ Language Options
Disable the warning about a throw-expression that will immediately
result in a call to @code{terminate}.
+@item -Wno-vexing-parse @r{(C++ and Objective-C++ only)}
+@opindex Wvexing-parse
+@opindex Wno-vexing-parse
+Warn about the most vexing parse syntactic ambiguity. This warns about
+the cases when a declaration looks like a variable definition, but the
+C++ language requires it to be interpreted as a function declaration.
+For instance:
+
+@smallexample
+void f(double a) @{
+ int i(); // extern int i (void);
+ int n(int(a)); // extern int n (int);
+@}
+@end smallexample
+
+Another example:
+
+@smallexample
+struct S @{ S(int); @};
+void f(double a) @{
+ S x(int(a)); // extern struct S x (int);
+ S y(int()); // extern struct S y (int (*) (void));
+ S z(); // extern struct S z (void);
+@}
+@end smallexample
+
+The warning will suggest options how to deal with such an ambiguity; e.g.,
+it can suggest removing the parentheses or using braces instead.
+
+This warning is enabled by default.
+
@item -Wno-class-conversion @r{(C++ and Objective-C++ only)}
@opindex Wno-class-conversion
@opindex Wclass-conversion
int
main ()
{
- int foo ();
+ int foo (); // { dg-warning "empty parentheses" }
int foo (int);
int foo (int, int);
int a, b = 10;
int
main ()
{
- int foo ();
+ int foo (); // { dg-warning "empty parentheses" }
int a, b = 10;
a = foo<; // { dg-error "invalid template-argument-list|invalid" }
a = foo < b; // { dg-error "invalid template-argument-list|invalid" }
struct B {
B(A, A, int, int, int, int);
void m_fn1(SubGraphIsoMapCallback p1) {
- __normal_iterator __trans_tmp_1();
+ __normal_iterator __trans_tmp_1(); // { dg-warning "empty parentheses" }
p1(__trans_tmp_1, 0);
}
};
int main ()
{
- auto foo ();
+ extern auto foo ();
}
class XclImpRoot : XclRoot {};
class XclImpColRowSettings : XclImpRoot {};
void lcl_ExportExcelBiff() {
-XclRootData aExpData();
+extern XclRootData aExpData();
}
{
Foo()
{
- int t(int()); // Error
+ int t(int()); // { dg-warning "parentheses were disambiguated" }
}
};
int main()
{
- int t(int()); // OK
+ int t(int()); // { dg-warning "parentheses were disambiguated" }
Foo<> a; // Error
}
template <typename aw, typename i, typename ax> void ay(aw, i, ax) {
// Not sure if this has been creduced from an initialization of a
// variable to a block-scope extern function decl
- au<c::e<ap<typename ak<i>::o>::f> > az2();
+ au<c::e<ap<typename ak<i>::o>::f> > az2(); // { dg-warning "empty parentheses" }
}
void v() {
ad a;
--- /dev/null
+// PR c++/25814
+// { dg-do compile }
+// Test -Wvexing-parse.
+
+struct T { };
+
+struct X {
+ X();
+};
+
+struct S {
+ S(int);
+ S foo (int (int));
+ S(T);
+ int m;
+};
+
+struct W {
+ W();
+ W(X, X);
+ int m;
+};
+
+int g;
+int g1(int(g));
+int g2(int());
+void fg(int);
+
+void
+fn1 (double (a))
+{
+ extern int f0();
+ extern int f1(int(a));
+ int f2(int(a)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ int (*f3)(int(a));
+ int f4(int a);
+ int f5(int()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ int f6(...);
+ int f7((int(a)));
+ int (f8);
+ int f9(S(s)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ int(f10) __attribute__(());
+ int(f11(int()));
+ if (int(a) = 1) { }
+ int j, k, l(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ int m, f12(int(j)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+
+ T t1(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ T t2(T()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ /* Declares a variable t3. */
+ T(t3);
+ T t4(), // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ t5(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+
+ extern S s1(int(a));
+ S s2(int(a)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ S s3(int a);
+ S s4(int()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ S s5(int(int)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ S s6(...);
+ S s7((int(a)));
+ S s8((int)a);
+ S s9 = int(a);
+ S(T());
+ S s10(S()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ S s11(T());
+ S s12(X()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ S s13 = S(T());
+ S(T()).foo(0);
+ S (S::*foo)(int (int));
+ S(*s14)(int(a));
+ S s15(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ S s16(void);
+
+ /* Don't warn here. */
+ void fv1(int(a));
+ void fv2(int());
+ void (fv3)();
+ void (fv4)(void);
+ void (fv5)(int);
+
+ int n(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ int (n2)(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ int n3(void);
+
+ typedef int F(const char*);
+ typedef int F2();
+ typedef int F3() const;
+ typedef int F4(int(a)) const;
+
+ W w(X(), X()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+}
+
+struct C1 {
+ C1(int);
+};
+
+struct C2 {
+ C2(C1, int);
+};
+
+template<int N> int value() { return N; }
+
+void
+fn2 ()
+{
+ int i = 0;
+ C2 c2(C1(int(i)), i);
+ C1(value<0>());
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile { target c++11 } }
+// Test -Wvexing-parse. C++11 features.
+
+struct X { };
+struct T {
+ T(X);
+};
+
+void
+fn1 (double (a))
+{
+ auto l = [](){
+ int f(int(a)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ };
+
+ [[noreturn]] int(e)(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+
+ T t1{X()};
+ T t2(X{});
+ T t3{X{}};
+
+ using U = int();
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fdiagnostics-show-caret" }
+// Test -Wvexing-parse's fix-it hints in C++11.
+
+#include <initializer_list>
+
+struct X { };
+
+struct S {
+ S(X);
+ S(std::initializer_list<X>);
+ int m;
+};
+
+struct T {
+ T(X);
+ int m;
+};
+
+struct W {
+ W();
+ W(std::initializer_list<X>);
+ int m;
+};
+
+struct U {
+ U();
+ int m;
+};
+
+int
+main ()
+{
+ /*
+ Careful what we're suggesting:
+ S a((X())) -> S(X)
+ S a({X()}) -> (std::initializer_list<X>)
+ S a{X()} -> (std::initializer_list<X>)
+ */
+ S a(X()); // { dg-warning "6:parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ S a(X());
+ ^~~~~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:add parentheses to declare a variable" "" { target *-*-* } 41 }
+ /* { dg-begin-multiline-output "" }
+ S a(X());
+ ^~~~~
+ ( )
+ { dg-end-multiline-output "" } */
+
+ T t(X()); // { dg-warning "6:parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ T t(X());
+ ^~~~~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:replace parentheses with braces to declare a variable" "" { target *-*-* } 53 }
+ /* { dg-begin-multiline-output "" }
+ T t(X());
+ ^~~~~
+ -
+ { -
+ }
+ { dg-end-multiline-output "" } */
+
+ int n( ); // { dg-warning "8:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ int n( );
+ ^~~~~
+ { dg-end-multiline-output "" } */
+ // { dg-message "8:remove parentheses to default-initialize a variable" "" { target *-*-* } 67 }
+ /* { dg-begin-multiline-output "" }
+ int n( );
+ ^~~~~
+ -----
+ { dg-end-multiline-output "" } */
+ // { dg-message "8:or replace parentheses with braces to value-initialize a variable" "" { target *-*-* } 67 }
+
+ S s(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ S s();
+ ^~
+ { dg-end-multiline-output "" } */
+
+ X x(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ X x();
+ ^~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:remove parentheses to default-initialize a variable" "" { target *-*-* } 86 }
+ /* { dg-begin-multiline-output "" }
+ X x();
+ ^~
+ --
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:or replace parentheses with braces to aggregate-initialize a variable" "" { target *-*-* } 86 }
+
+ W w(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ W w();
+ ^~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:remove parentheses to default-initialize a variable" "" { target *-*-* } 99 }
+ /* { dg-begin-multiline-output "" }
+ W w();
+ ^~
+ --
+ { dg-end-multiline-output "" } */
+
+ T t2(); // { dg-warning "7:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ T t2();
+ ^~
+ { dg-end-multiline-output "" } */
+
+ U u(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ U u();
+ ^~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:remove parentheses to default-initialize a variable" "" { target *-*-* } 117 }
+ /* { dg-begin-multiline-output "" }
+ U u();
+ ^~
+ --
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:or replace parentheses with braces to value-initialize a variable" "" { target *-*-* } 117 }
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile { target c++98_only } }
+// { dg-additional-options "-fdiagnostics-show-caret" }
+// Test -Wvexing-parse's fix-it hints in C++98.
+
+struct X { };
+
+struct T {
+ T(X);
+ int m;
+};
+
+struct U {
+ U();
+ int m;
+};
+
+int
+main ()
+{
+ T t(X()); // { dg-warning "6:parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ T t(X());
+ ^~~~~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:add parentheses to declare a variable" "" { target *-*-* } 21 }
+ /* { dg-begin-multiline-output "" }
+ T t(X());
+ ^~~~~
+ ( )
+ { dg-end-multiline-output "" } */
+
+ int n( ); // { dg-warning "8:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ int n( );
+ ^~~~~
+ { dg-end-multiline-output "" } */
+ // { dg-message "8:remove parentheses to default-initialize a variable" "" { target *-*-* } 33 }
+ /* { dg-begin-multiline-output "" }
+ int n( );
+ ^~~~~
+ -----
+ { dg-end-multiline-output "" } */
+
+ T y(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ T y();
+ ^~
+ { dg-end-multiline-output "" } */
+
+ X x(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ X x();
+ ^~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:remove parentheses to default-initialize a variable" "" { target *-*-* } 51 }
+ /* { dg-begin-multiline-output "" }
+ X x();
+ ^~
+ --
+ { dg-end-multiline-output "" } */
+
+ U u(); // { dg-warning "6:empty parentheses were disambiguated as a function declaration" }
+ /* { dg-begin-multiline-output "" }
+ U u();
+ ^~
+ { dg-end-multiline-output "" } */
+ // { dg-message "6:remove parentheses to default-initialize a variable" "" { target *-*-* } 63 }
+ /* { dg-begin-multiline-output "" }
+ U u();
+ ^~
+ --
+ { dg-end-multiline-output "" } */
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile }
+// Test -Wvexing-parse in a template.
+
+struct X { };
+
+template<typename T>
+void fn ()
+{
+ T t(); // { dg-warning "empty parentheses were disambiguated as a function declaration" }
+ T a(X()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ X x(T()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ int i(T()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile }
+// Test from Wikipedia.
+
+class Timer {
+ public:
+ Timer();
+};
+
+class TimeKeeper {
+ public:
+ TimeKeeper(const Timer& t);
+
+ int get_time();
+};
+
+void f(double adouble) {
+ int i(int(adouble)); // { dg-warning "parentheses were disambiguated as a function declaration" }
+}
+
+int main() {
+ TimeKeeper time_keeper(Timer()); // { dg-warning "parentheses were disambiguated as a function declaration" }
+ return time_keeper.get_time(); // { dg-error "request for member" }
+}
--- /dev/null
+// PR c++/25814
+// { dg-do compile }
+
+struct X { };
+struct W {
+ W(X, X);
+};
+
+void
+fn ()
+{
+ W w1(X(), X()); // { dg-warning "parentheses" }
+ W w2(X(a), X()); // { dg-warning "parentheses" }
+ W w3(X(), X(a)); // { dg-warning "parentheses" }
+ W w4(X(a), X(b)); // { dg-warning "parentheses" }
+ W w5(X, X);
+ W w6(X(a), X);
+ W w7(X, X(a));
+ W w8(X(a), X()); // { dg-warning "parentheses" }
+ W w9(X, X());
+ W w10(X, X());
+
+ // Not function declarations.
+ W z1(X(), (X()));
+ W z2((X()), X());
+ W z3((X()), (X()));
+}
int main()
{
- DBpathrec a(), b();
+ DBpathrec a(), b(); // { dg-warning "empty parentheses" }
a = b;// { dg-error "" } non-lvalue in assignment.*
}
ccList <T> cc_List<T>::copy (){}
int main (int, char **) {
- ccList <int> size1();
+ ccList <int> size1(); // { dg-warning "empty parentheses" }
}
{
double a = 2.0;
- S x(int (a));
+ S x(int (a)); // { dg-warning "parentheses were disambiguated" }
if (count > 0)
{ printf ("FAIL\n"); return 1; }
else
void bee () {
int i = 0;
- for (int fun() = 0; i != 2; ++i) { // { dg-warning "extern" "extern" }
+ for (int fun() = 0; i != 2; ++i) { // { dg-warning "extern|empty parentheses" "extern" }
// { dg-error "initialized" "init" { target *-*-* } .-1 }
}
}
int main ()
{
- int f ();
+ int f (); // { dg-warning "empty parentheses" }
return f ();
}
{
// local-extern :)
CVector<int> v(); // { dg-message "old declaration" }
+ // { dg-warning "empty parentheses" "" { target *-*-* } .-1 }
return v; // { dg-error "convert" }
}
CVector<long> g() const
{
CVector<long> v(); // { dg-error "ambiguating new" }
+ // { dg-warning "empty parentheses" "" { target *-*-* } .-1 }
return v; // { dg-error "convert" }
}
};
void
test02()
{
- std::reference_wrapper<int> purr();
+ std::reference_wrapper<int> purr(); // { dg-warning "empty parentheses" }
// error, ambiguous: ICS exists from int prvalue to
// reference_wrapper<int> and from reference_wrapper<int> to int
void test01()
{
- int gen();
+ int gen(); // { dg-warning "empty parentheses" }
int a[2];
std::generate_n(a, a+2, &gen);
}