mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-26 07:50:27 +08:00
re PR c++/37962 (ICE with (auto*) casts)
PR c++/37962 cp/ * parser.c (cp_parser_type_id): Complain about auto. * decl.c (grokdeclarator): Complain about parameters and conversion functions declared with auto. * call.c (standard_conversion): Use CLASS_TYPE_P instead of MAYBE_CLASS_TYPE_P. * cp-tree.h (TYPE_NON_AGGREGATE_CLASS): Likewise. testsuite/ * g++.dg/cpp0x/auto[38].C: Adjust expected errors. * g++.dg/cpp0x/auto9.C: New test. * g++.dg/cpp0x/auto10.C: New test. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r141970
This commit is contained in:
parent
43db6c722a
commit
3f50c84611
@ -1,3 +1,15 @@
|
||||
2008-11-18 Jason Merrill <jason@redhat.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/37962
|
||||
* parser.c (cp_parser_type_id): Complain about auto.
|
||||
* decl.c (grokdeclarator): Complain about parameters and
|
||||
conversion functions declared with auto.
|
||||
|
||||
* call.c (standard_conversion): Use CLASS_TYPE_P instead of
|
||||
MAYBE_CLASS_TYPE_P.
|
||||
* cp-tree.h (TYPE_NON_AGGREGATE_CLASS): Likewise.
|
||||
|
||||
2008-11-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/36089
|
||||
|
@ -814,8 +814,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
|
||||
else if (!same_type_p (fbase, tbase))
|
||||
return NULL;
|
||||
}
|
||||
else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (from))
|
||||
&& MAYBE_CLASS_TYPE_P (TREE_TYPE (to))
|
||||
else if (CLASS_TYPE_P (TREE_TYPE (from))
|
||||
&& CLASS_TYPE_P (TREE_TYPE (to))
|
||||
/* [conv.ptr]
|
||||
|
||||
An rvalue of type "pointer to cv D," where D is a
|
||||
|
@ -2824,7 +2824,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
||||
#define CLASSTYPE_NON_AGGREGATE(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate)
|
||||
#define TYPE_NON_AGGREGATE_CLASS(NODE) \
|
||||
(MAYBE_CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
|
||||
(CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
|
||||
|
||||
/* Nonzero if there is a user-defined X::op=(x&) for this class. */
|
||||
#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref)
|
||||
|
@ -8053,6 +8053,12 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
|| storage_class == sc_extern
|
||||
|| thread_p)
|
||||
error ("storage class specifiers invalid in parameter declarations");
|
||||
|
||||
if (type_uses_auto (type))
|
||||
{
|
||||
error ("parameter declared %<auto%>");
|
||||
type = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Give error if `virtual' is used outside of class declaration. */
|
||||
@ -8246,23 +8252,29 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
{
|
||||
if (type_uses_auto (type))
|
||||
{
|
||||
if (!declarator->u.function.late_return_type)
|
||||
if (sfk == sfk_conversion)
|
||||
{
|
||||
error ("%qs function uses auto type specifier without"
|
||||
error ("invalid use of %<auto%> in conversion operator");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (!declarator->u.function.late_return_type)
|
||||
{
|
||||
error ("%qs function uses %<auto%> type specifier without"
|
||||
" late return type", name);
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (!is_auto (type))
|
||||
{
|
||||
error ("%qs function with late return type not using"
|
||||
" auto type specifier as its type", name);
|
||||
error ("%qs function with late return type has"
|
||||
" %qT as its type rather than plain %<auto%>",
|
||||
name, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (declarator->u.function.late_return_type)
|
||||
{
|
||||
error ("%qs function with late return type not declared"
|
||||
" with auto type specifier", name);
|
||||
" with %<auto%> type specifier", name);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
@ -13693,6 +13693,13 @@ cp_parser_type_id (cp_parser* parser)
|
||||
if (!cp_parser_parse_definitely (parser))
|
||||
abstract_declarator = NULL;
|
||||
|
||||
if (type_specifier_seq.type
|
||||
&& type_uses_auto (type_specifier_seq.type))
|
||||
{
|
||||
error ("invalid use of %<auto%>");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return groktypename (&type_specifier_seq, abstract_declarator);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
2008-11-18 Jason Merrill <jason@redhat.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/37962
|
||||
* g++.dg/cpp0x/auto[38].C: Adjust expected errors.
|
||||
* g++.dg/cpp0x/auto9.C: New test.
|
||||
* g++.dg/cpp0x/auto10.C: New test.
|
||||
|
||||
2008-11-17 Adam Nemet <anemet@caviumnetworks.com>
|
||||
|
||||
* gcc.c-torture/execute/20081117-1.c: New test.
|
||||
|
22
gcc/testsuite/g++.dg/cpp0x/auto10.C
Normal file
22
gcc/testsuite/g++.dg/cpp0x/auto10.C
Normal file
@ -0,0 +1,22 @@
|
||||
// Positive test for auto
|
||||
// { dg-do run }
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
#include <typeinfo>
|
||||
extern "C" void abort();
|
||||
|
||||
int main()
|
||||
{
|
||||
if (auto i = 42L)
|
||||
{
|
||||
if (typeid (i) != typeid (long int))
|
||||
abort ();
|
||||
}
|
||||
|
||||
while (auto i = 1)
|
||||
{
|
||||
if (typeid (i) != typeid (int))
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ struct A { };
|
||||
|
||||
A<int> A1;
|
||||
// CWG issue 625
|
||||
A<auto> A2 = A1; // { dg-error "auto" }
|
||||
A<auto> A2 = A1; // { dg-error "" }
|
||||
|
||||
auto foo() { } // { dg-error "auto" }
|
||||
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
auto f1 () -> int;
|
||||
auto f2 (); // { dg-error "without late return type" }
|
||||
int f3 () -> int; // { dg-error "with auto type specifier" }
|
||||
auto *f4 () -> int; // { dg-error "not using auto" }
|
||||
int f3 () -> int; // { dg-error "late return type" }
|
||||
auto *f4 () -> int; // { dg-error "late return type" }
|
||||
|
||||
struct A
|
||||
{
|
||||
auto f5 () const -> int;
|
||||
auto f6 (); // { dg-error "without late return type" }
|
||||
int f7 () -> int; // { dg-error "with auto type specifier" }
|
||||
auto *f8 () -> int; // { dg-error "not using auto" }
|
||||
int f7 () -> int; // { dg-error "late return type" }
|
||||
auto *f8 () -> int; // { dg-error "late return type" }
|
||||
};
|
||||
|
121
gcc/testsuite/g++.dg/cpp0x/auto9.C
Normal file
121
gcc/testsuite/g++.dg/cpp0x/auto9.C
Normal file
@ -0,0 +1,121 @@
|
||||
// PR c++/37962
|
||||
// Negative test for auto
|
||||
// { dg-do compile }
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
#include <typeinfo>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int i = *(auto *) 0; // { dg-error "auto" }
|
||||
struct A *p = (auto *) 0; // { dg-error "auto" }
|
||||
int *q = static_cast <auto *>(0); // { dg-error "auto" }
|
||||
const int *r = const_cast <auto *>(q); // { dg-error "auto" }
|
||||
const std::type_info &t1 = typeid (auto); // { dg-error "auto" }
|
||||
const std::type_info &t2 = typeid (auto *); // { dg-error "auto" }
|
||||
|
||||
struct A
|
||||
{
|
||||
operator auto (); // { dg-error "auto" }
|
||||
operator auto *(); // { dg-error "auto" }
|
||||
};
|
||||
|
||||
struct A2
|
||||
{
|
||||
operator auto () -> int; // { dg-error "invalid use of" }
|
||||
operator auto *() -> int; // { dg-error "auto" }
|
||||
};
|
||||
|
||||
template <typename> struct B
|
||||
{
|
||||
enum { e };
|
||||
};
|
||||
|
||||
template <typename T> struct C
|
||||
{
|
||||
C () : i () {}
|
||||
int i;
|
||||
};
|
||||
|
||||
bool d = (auto (A::*)()) 0; // { dg-error "auto" }
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
(auto) { 0 }; // { dg-error "auto" }
|
||||
C<int> c;
|
||||
dynamic_cast<auto> (c); // { dg-error "auto" }
|
||||
reinterpret_cast<auto> (c); // { dg-error "auto" }
|
||||
int i = auto (0); // { dg-error "auto" }
|
||||
auto p1 = new (auto); // { dg-error "auto" }
|
||||
auto p2 = new (auto) (42); // { dg-error "invalid use of|deduce" }
|
||||
offsetof (auto, fld); // { dg-error "auto" }
|
||||
offsetof (auto *, fld); // { dg-error "auto" }
|
||||
sizeof (auto); // { dg-error "auto" }
|
||||
sizeof (auto *); // { dg-error "auto" }
|
||||
}
|
||||
|
||||
void
|
||||
foo2 (void)
|
||||
{
|
||||
__alignof__ (auto); // { dg-error "auto" }
|
||||
__alignof__ (auto *); // { dg-error "auto" }
|
||||
__typeof__ (auto) v1; // { dg-error "auto" }
|
||||
__typeof__ (auto *) v2; // { dg-error "auto" }
|
||||
__is_class (auto); // { dg-error "auto|expected" }
|
||||
__is_pod (auto *); // { dg-error "auto|expected" }
|
||||
__is_base_of (int, auto); // { dg-error "auto|expected" }
|
||||
__is_base_of (auto, int); // { dg-error "auto|expected" }
|
||||
__is_base_of (auto, auto *); // { dg-error "auto|expected" }
|
||||
}
|
||||
|
||||
B<auto> b; // { dg-error "auto|invalid" }
|
||||
C<auto> c; // { dg-error "auto|invalid" }
|
||||
C<auto *> c2; // { dg-error "auto|invalid" }
|
||||
|
||||
enum : auto { EE = 0 }; // { dg-error "must be an integral type" }
|
||||
enum struct D : auto * { FF = 0 }; // { dg-error "declar|expected" }
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
try { } catch (auto i) { } // { dg-error "invalid use of" }
|
||||
try { } catch (auto) { } // { dg-error "invalid use of" }
|
||||
try { } catch (auto *i) { } // { dg-error "invalid use of" }
|
||||
try { } catch (auto *) { } // { dg-error "invalid use of" }
|
||||
}
|
||||
|
||||
void
|
||||
baz (int i, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, i);
|
||||
va_arg (ap, auto); // { dg-error "invalid use of" }
|
||||
va_arg (ap, auto *); // { dg-error "invalid use of|expected" }
|
||||
va_arg (ap, auto &); // { dg-error "invalid use of|expected" }
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
template <typename T = auto> struct E {}; // { dg-error "invalid use of" }
|
||||
template <class T = auto *> struct F {}; // { dg-error "invalid use of|expected" }
|
||||
|
||||
auto fnlate () -> auto; // { dg-error "invalid use of" }
|
||||
auto fnlate2 () -> auto *; // { dg-error "invalid use of|expected" }
|
||||
|
||||
void
|
||||
badthrow () throw (auto) // { dg-error "invalid use of" }
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
badthrow2 () throw (auto &) // { dg-error "invalid use of|expected" }
|
||||
{
|
||||
}
|
||||
|
||||
template <auto V = 4> struct G {}; // { dg-error "auto" }
|
||||
|
||||
template <typename T> struct H { H (); ~H (); };
|
||||
H<auto> h; // { dg-error "invalid" }
|
||||
|
||||
void qq (auto); // { dg-error "auto" }
|
||||
void qr (auto*); // { dg-error "auto" }
|
Loading…
x
Reference in New Issue
Block a user