2
0
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:
Jason Merrill 2008-11-18 13:11:32 -05:00 committed by Jason Merrill
parent 43db6c722a
commit 3f50c84611
10 changed files with 195 additions and 13 deletions

@ -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.

@ -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" }
};

@ -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" }