From 3f50c84611bd118046835a42512360c40d2aa299 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 18 Nov 2008 13:11:32 -0500 Subject: [PATCH] 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 From-SVN: r141970 --- gcc/cp/ChangeLog | 12 ++++ gcc/cp/call.c | 4 +- gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 22 +++++-- gcc/cp/parser.c | 7 +++ gcc/testsuite/ChangeLog | 8 +++ gcc/testsuite/g++.dg/cpp0x/auto10.C | 22 +++++++ gcc/testsuite/g++.dg/cpp0x/auto3.C | 2 +- gcc/testsuite/g++.dg/cpp0x/auto8.C | 8 +-- gcc/testsuite/g++.dg/cpp0x/auto9.C | 121 ++++++++++++++++++++++++++++++++++++ 10 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto10.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f184028..4353263 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2008-11-18 Jason Merrill + Jakub Jelinek + + 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 PR c++/36089 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4d86a44..af3fd99 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b79b819..9f10ed1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 945b947..997c580 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 %"); + 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 ("invalid use of % in conversion operator"); + return error_mark_node; + } + else if (!declarator->u.function.late_return_type) { - error ("%qs function uses auto type specifier without" + error ("%qs function uses % 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 %", + 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 % type specifier", name); return error_mark_node; } } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ba8759c..5c1f849 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 %"); + return error_mark_node; + } + return groktypename (&type_specifier_seq, abstract_declarator); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0af6cad..8ed4c3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2008-11-18 Jason Merrill + Jakub Jelinek + + 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 * gcc.c-torture/execute/20081117-1.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/auto10.C b/gcc/testsuite/g++.dg/cpp0x/auto10.C new file mode 100644 index 0000000..9b89291 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto10.C @@ -0,0 +1,22 @@ +// Positive test for auto +// { dg-do run } +// { dg-options "-std=c++0x" } + +#include +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; + } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/auto3.C b/gcc/testsuite/g++.dg/cpp0x/auto3.C index 769d987..3cea856 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto3.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C @@ -17,7 +17,7 @@ struct A { }; A A1; // CWG issue 625 -A A2 = A1; // { dg-error "auto" } +A A2 = A1; // { dg-error "" } auto foo() { } // { dg-error "auto" } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto8.C b/gcc/testsuite/g++.dg/cpp0x/auto8.C index d724d79..e45204f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto8.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto8.C @@ -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" } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/auto9.C b/gcc/testsuite/g++.dg/cpp0x/auto9.C new file mode 100644 index 0000000..7dcf487 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto9.C @@ -0,0 +1,121 @@ +// PR c++/37962 +// Negative test for auto +// { dg-do compile } +// { dg-options "-std=c++0x" } + +#include +#include +#include + +int i = *(auto *) 0; // { dg-error "auto" } +struct A *p = (auto *) 0; // { dg-error "auto" } +int *q = static_cast (0); // { dg-error "auto" } +const int *r = const_cast (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 struct B +{ + enum { e }; +}; + +template struct C +{ + C () : i () {} + int i; +}; + +bool d = (auto (A::*)()) 0; // { dg-error "auto" } + +void +foo () +{ + (auto) { 0 }; // { dg-error "auto" } + C c; + dynamic_cast (c); // { dg-error "auto" } + reinterpret_cast (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 b; // { dg-error "auto|invalid" } +C c; // { dg-error "auto|invalid" } +C 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 struct E {}; // { dg-error "invalid use of" } +template 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 struct G {}; // { dg-error "auto" } + +template struct H { H (); ~H (); }; +H h; // { dg-error "invalid" } + +void qq (auto); // { dg-error "auto" } +void qr (auto*); // { dg-error "auto" } -- 2.7.4