From 4753e009664aa5d4cdf0ce86a03224f5bc1f9d7b Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 3 Jun 2015 17:08:39 +0000 Subject: [PATCH] decl.c (check_tag_decl): Use declspecs->locations as locations in error_at and warning_at calls. /cp 2015-06-03 Paolo Carlini * decl.c (check_tag_decl): Use declspecs->locations as locations in error_at and warning_at calls. /testsuite 2015-06-03 Paolo Carlini * g++.dg/cpp0x/decl-loc1.C: New. * g++.dg/cpp0x/constexpr-neg1.C: Adjust. * g++.dg/cpp0x/constexpr-object1.C: Likewise. * g++.dg/init/ctor8.C: Likewise. * g++.dg/parse/semicolon4.C: Likewise. From-SVN: r224097 --- gcc/cp/ChangeLog | 5 ++ gcc/cp/decl.c | 50 ++++++++++++------- gcc/testsuite/ChangeLog | 8 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C | 4 +- .../g++.dg/cpp0x/constexpr-object1.C | 4 +- gcc/testsuite/g++.dg/cpp0x/decl-loc1.C | 13 +++++ gcc/testsuite/g++.dg/init/ctor8.C | 2 +- gcc/testsuite/g++.dg/parse/semicolon4.C | 2 +- 8 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decl-loc1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a4ab191ad8c..2c61d557716 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-06-03 Paolo Carlini + + * decl.c (check_tag_decl): Use declspecs->locations as locations in + error_at and warning_at calls. + 2015-06-03 Marek Polacek PR sanitizer/66190 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6140ab6770a..9d20b9487d2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4488,30 +4488,46 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, else { - if (decl_spec_seq_has_spec_p (declspecs, ds_inline) - || decl_spec_seq_has_spec_p (declspecs, ds_virtual)) - error ("%qs can only be specified for functions", - decl_spec_seq_has_spec_p (declspecs, ds_inline) - ? "inline" : "virtual"); + if (decl_spec_seq_has_spec_p (declspecs, ds_inline)) + error_at (declspecs->locations[ds_inline], + "% can only be specified for functions"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_virtual)) + error_at (declspecs->locations[ds_virtual], + "% can only be specified for functions"); else if (saw_friend && (!current_class_type || current_scope () != current_class_type)) - error ("% can only be specified inside a class"); + error_at (declspecs->locations[ds_friend], + "% can only be specified inside a class"); else if (decl_spec_seq_has_spec_p (declspecs, ds_explicit)) - error ("% can only be specified for constructors"); + error_at (declspecs->locations[ds_explicit], + "% can only be specified for constructors"); else if (declspecs->storage_class) - error ("a storage class can only be specified for objects " - "and functions"); - else if (decl_spec_seq_has_spec_p (declspecs, ds_const) - || decl_spec_seq_has_spec_p (declspecs, ds_volatile) - || decl_spec_seq_has_spec_p (declspecs, ds_restrict) - || decl_spec_seq_has_spec_p (declspecs, ds_thread)) - error ("qualifiers can only be specified for objects " - "and functions"); + error_at (declspecs->locations[ds_storage_class], + "a storage class can only be specified for objects " + "and functions"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_const)) + error_at (declspecs->locations[ds_const], + "% can only be specified for objects and " + "functions"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_volatile)) + error_at (declspecs->locations[ds_volatile], + "% can only be specified for objects and " + "functions"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_restrict)) + error_at (declspecs->locations[ds_restrict], + "%<__restrict%> can only be specified for objects and " + "functions"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_thread)) + error_at (declspecs->locations[ds_thread], + "%<__thread%> can only be specified for objects " + "and functions"); else if (saw_typedef) - warning (0, "% was ignored in this declaration"); + warning_at (declspecs->locations[ds_typedef], 0, + "% was ignored in this declaration"); else if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr)) - error ("% cannot be used for type declarations"); + error_at (declspecs->locations[ds_constexpr], + "% cannot be used for type declarations"); } if (declspecs->attributes && warn_attributes && declared_type) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5d882df0c9..53c7018f3e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-06-03 Paolo Carlini + + * g++.dg/cpp0x/decl-loc1.C: New. + * g++.dg/cpp0x/constexpr-neg1.C: Adjust. + * g++.dg/cpp0x/constexpr-object1.C: Likewise. + * g++.dg/init/ctor8.C: Likewise. + * g++.dg/parse/semicolon4.C: Likewise. + 2015-06-03 Marek Polacek PR sanitizer/66190 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C index dfa1d6bf128..58b5d32c37c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C @@ -5,12 +5,12 @@ constexpr int square(int x); // { dg-message "never defined" } // error: pixel is a type -constexpr struct pixel { +constexpr struct pixel { // { dg-error "constexpr" } int x; int y; // OK: declaration constexpr pixel(int); -}; // { dg-error "constexpr" } +}; constexpr pixel::pixel(int a) // OK: definition : x(square(a)), y(square(a)) // { dg-error "square" } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-object1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-object1.C index da9e3e4ab3f..1861d404782 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-object1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-object1.C @@ -22,8 +22,8 @@ const constexpr A1 a3 = A1(); volatile constexpr A1 a4 = A1(); // { dg-bogus "both .volatile. and .constexpr. cannot" } // error: on type declaration -constexpr struct pixel +constexpr struct pixel // { dg-error "cannot be used for type declarations" } { int x; int y; -}; // { dg-error "cannot be used for type declarations" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/decl-loc1.C b/gcc/testsuite/g++.dg/cpp0x/decl-loc1.C new file mode 100644 index 00000000000..072ca7d6504 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decl-loc1.C @@ -0,0 +1,13 @@ +// { dg-do compile { target c++11 } } + +inline struct A; // { dg-error "1:'inline'" } +virtual struct B; // { dg-error "1:'virtual'" } +friend struct C; // { dg-error "1:'friend'" } +explicit struct D; // { dg-error "1:'explicit'" } +mutable struct E; // { dg-error "1:a storage class" } +const struct F; // { dg-error "1:'const'" } +volatile struct G; // { dg-error "1:'volatile'" } +__restrict struct H; // { dg-error "1:'__restrict'" } +__thread struct I; // { dg-error "1:'__thread'" } +typedef struct J; // { dg-warning "1:'typedef'" } +constexpr struct K; // { dg-error "1:'constexpr'" } diff --git a/gcc/testsuite/g++.dg/init/ctor8.C b/gcc/testsuite/g++.dg/init/ctor8.C index 3c37790c0c4..ce403a6bb61 100644 --- a/gcc/testsuite/g++.dg/init/ctor8.C +++ b/gcc/testsuite/g++.dg/init/ctor8.C @@ -2,7 +2,7 @@ typedef struct S { // { dg-error "reference" "" { target c++11 } } int &r; -}; // { dg-warning "'typedef' was ignored" } +}; // { dg-warning "1:'typedef' was ignored" "" { target *-*-* } 3 } S f () { diff --git a/gcc/testsuite/g++.dg/parse/semicolon4.C b/gcc/testsuite/g++.dg/parse/semicolon4.C index adba7a873c0..5135ec14b1f 100644 --- a/gcc/testsuite/g++.dg/parse/semicolon4.C +++ b/gcc/testsuite/g++.dg/parse/semicolon4.C @@ -22,7 +22,7 @@ struct OK3 struct E1 { int i; -} const; // { dg-error "qualifiers can only be specified for objects and functions" } +} const; // { dg-error "'const' can only be specified for objects and functions" } void foo ( struct E2 -- 2.30.2