[cfe-commits] r139102 - in /cfe/trunk: include/clang/Basic/ lib/Parse/ lib/Sema/ test/CXX/class/class.friend/ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/ test/Misc/ test/SemaCXX/
Richard Smith
richard-llvm at metafoo.co.uk
Sun Sep 4 12:54:14 PDT 2011
Author: rsmith
Date: Sun Sep 4 14:54:14 2011
New Revision: 139102
URL: http://llvm.org/viewvc/llvm-project?rev=139102&view=rev
Log:
PR10458: Finesse behaviour of C++0x features when in pre-0x mode. Accept for-range and auto with an ExtWarn, and produce a -Wc++0x-compat warning in C++98 mode when auto is used as a storage class.
Added:
cfe/trunk/test/SemaCXX/PR10458.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/test/CXX/class/class.friend/p6.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
cfe/trunk/test/Misc/warning-flags.c
cfe/trunk/test/SemaCXX/auto-cxx0x.cpp
cfe/trunk/test/SemaCXX/auto-cxx98.cpp
cfe/trunk/test/SemaCXX/class.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Sep 4 14:54:14 2011
@@ -28,10 +28,6 @@
def ext_extra_ivar_semi : Extension<
"extra ';' inside instance variable list">;
-def auto_storage_class : ExtWarn<
- "'auto' storage class specifier is redundant and will be "
- "removed in future releases">;
-
def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
def ext_plain_complex : ExtWarn<
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
@@ -198,6 +194,16 @@
def ext_generalized_initializer_lists : ExtWarn<
"generalized initializer lists are a C++0x extension unsupported in Clang">,
InGroup<CXX0x>;
+def ext_auto_type_specifier : ExtWarn<
+ "'auto' type specifier is a C++0x extension">, InGroup<CXX0x>;
+def warn_auto_storage_class : Warning<
+ "'auto' storage class specifier is redundant and incompatible with C++0x">,
+ InGroup<CXX0xCompat>;
+def ext_auto_storage_class : ExtWarn<
+ "'auto' storage class specifier is not permitted in C++0x, and will not "
+ "be supported in future releases">;
+def ext_for_range : ExtWarn<
+ "range-based for loop is a C++0x extension">, InGroup<CXX0x>;
def err_argument_required_after_attribute : Error<
"argument required after attribute">;
def err_missing_param : Error<"expected parameter declarator">;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Sep 4 14:54:14 2011
@@ -1769,16 +1769,14 @@
if (getLang().CPlusPlus0x) {
if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
- DiagID, getLang());
+ DiagID, getLang());
if (!isInvalid)
- Diag(Tok, diag::auto_storage_class)
+ Diag(Tok, diag::ext_auto_storage_class)
<< FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
- }
- else
+ } else
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
DiagID);
- }
- else
+ } else
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
DiagID, getLang());
break;
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sun Sep 4 14:54:14 2011
@@ -1313,6 +1313,9 @@
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (ForRangeInit.ParsedForRangeDecl()) {
+ if (!getLang().CPlusPlus0x)
+ Diag(ForRangeInit.ColonLoc, diag::ext_for_range);
+
ForRange = true;
} else if (Tok.is(tok::semi)) { // for (int x = 4;
ConsumeToken();
Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Sun Sep 4 14:54:14 2011
@@ -425,10 +425,23 @@
}
if (StorageClassSpec != SCS_unspecified) {
+ // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
+ bool isInvalid = true;
+ if (TypeSpecType == TST_unspecified && Lang.CPlusPlus) {
+ if (S == SCS_auto)
+ return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
+ if (StorageClassSpec == SCS_auto) {
+ isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
+ PrevSpec, DiagID);
+ assert(!isInvalid && "auto SCS -> TST recovery failed");
+ }
+ }
+
// Changing storage class is allowed only if the previous one
// was the 'extern' that is part of a linkage specification and
// the new storage class is 'typedef'.
- if (!(SCS_extern_in_linkage_spec &&
+ if (isInvalid &&
+ !(SCS_extern_in_linkage_spec &&
StorageClassSpec == SCS_extern &&
S == SCS_typedef))
return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
@@ -836,6 +849,27 @@
}
}
+ // If no type specifier was provided and we're parsing a language where
+ // the type specifier is not optional, but we got 'auto' as a storage
+ // class specifier, then assume this is an attempt to use C++0x's 'auto'
+ // type specifier.
+ // FIXME: Does Microsoft really support implicit int in C++?
+ if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().Microsoft &&
+ TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
+ TypeSpecType = TST_auto;
+ StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
+ TSTLoc = TSTNameLoc = StorageClassSpecLoc;
+ StorageClassSpecLoc = SourceLocation();
+ }
+ // Diagnose if we've recovered from an ill-formed 'auto' storage class
+ // specifier in a pre-C++0x dialect of C++.
+ if (!PP.getLangOptions().CPlusPlus0x && TypeSpecType == TST_auto)
+ Diag(D, TSTLoc, diag::ext_auto_type_specifier);
+ if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().CPlusPlus0x &&
+ StorageClassSpec == SCS_auto)
+ Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
+ << FixItHint::CreateRemoval(StorageClassSpecLoc);
+
// C++ [class.friend]p6:
// No storage-class-specifier shall appear in the decl-specifier-seq
// of a friend declaration.
Modified: cfe/trunk/test/CXX/class/class.friend/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.friend/p6.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.friend/p6.cpp (original)
+++ cfe/trunk/test/CXX/class/class.friend/p6.cpp Sun Sep 4 14:54:14 2011
@@ -3,7 +3,7 @@
class A {
friend static class B; // expected-error {{'static' is invalid in friend declarations}}
friend extern class C; // expected-error {{'extern' is invalid in friend declarations}}
- friend auto class D; // expected-error {{'auto' is invalid in friend declarations}}
+ friend auto class D; // expected-warning {{incompatible with C++0x}} expected-error {{'auto' is invalid in friend declarations}}
friend register class E; // expected-error {{'register' is invalid in friend declarations}}
friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}}
friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}}
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp Sun Sep 4 14:54:14 2011
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++0x-extensions
void f() {
auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
@@ -39,10 +40,12 @@
auto x = 5;
const auto *v = &x, u = 6;
static auto y = 0.0;
- auto int r; // expected-warning {{'auto' storage class specifier is redundant and will be removed in future releases}}
-
- same<decltype(x), int> xHasTypeInt;
- same<decltype(v), const int*> vHasTypeConstIntPtr;
- same<decltype(u), const int> uHasTypeConstInt;
- same<decltype(y), double> yHasTypeDouble;
+ // In C++98: 'auto' storage class specifier is redundant and incompatible with C++0x
+ // In C++0x: 'auto' storage class specifier is not permitted in C++0x, and will not be supported in future releases
+ auto int r; // expected-warning {{'auto' storage class specifier}}
+
+ same<__typeof(x), int> xHasTypeInt;
+ same<__typeof(v), const int*> vHasTypeConstIntPtr;
+ same<__typeof(u), const int> uHasTypeConstInt;
+ same<__typeof(y), double> yHasTypeDouble;
}
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp Sun Sep 4 14:54:14 2011
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++0x-extensions
template<typename T>
struct only {
@@ -19,7 +20,10 @@
for (; auto a = false; ) {
}
+ // FIXME: support 'auto' error recovery here in pre-C++0x mode.
+#if __has_feature(cxx_auto_type)
new const auto (0);
+#endif
new (auto) (0.0);
int arr[] = {1, 2, 3};
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp Sun Sep 4 14:54:14 2011
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++0x-extensions
template<typename T>
struct only {
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp Sun Sep 4 14:54:14 2011
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++0x-extensions
void f() {
auto a = 0, b = 0, c = 0;
auto d = 0, e = 0.0; // expected-error {{'int' in declaration of 'd' and deduced as 'double' in declaration of 'e'}}
@@ -18,6 +19,14 @@
}
void g() {
- auto a = 0, (*b)() -> void, c = 0;
- auto d = 0, (*e)() -> void, f = 0.0; // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
+ auto a = 0,
+#if __has_feature(cxx_trailing_return)
+ (*b)() -> void,
+#endif
+ c = 0;
+ auto d = 0, // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
+#if __has_feature(cxx_trailing_return)
+ (*e)() -> void,
+#endif
+ f = 0.0;
}
Modified: cfe/trunk/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/Misc/warning-flags.c (original)
+++ cfe/trunk/test/Misc/warning-flags.c Sun Sep 4 14:54:14 2011
@@ -18,12 +18,12 @@
The list of warnings below should NEVER grow. It should gradually shrink to 0.
CHECK: Warnings without flags (311):
-CHECK-NEXT: auto_storage_class
CHECK-NEXT: backslash_newline_space
CHECK-NEXT: charize_microsoft_ext
CHECK-NEXT: ext_anon_param_requires_type_specifier
CHECK-NEXT: ext_anonymous_struct_union_qualified
CHECK-NEXT: ext_array_init_copy
+CHECK-NEXT: ext_auto_storage_class
CHECK-NEXT: ext_binary_literal
CHECK-NEXT: ext_c1x_generic_selection
CHECK-NEXT: ext_c1x_static_assert
Added: cfe/trunk/test/SemaCXX/PR10458.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR10458.cpp?rev=139102&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/PR10458.cpp (added)
+++ cfe/trunk/test/SemaCXX/PR10458.cpp Sun Sep 4 14:54:14 2011
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+
+void f() {
+ int arr[] = { 1, 2, 3 };
+ for (auto &i : arr) { // expected-warning {{'auto' type specifier is a C++0x extension}} expected-warning {{range-based for loop is a C++0x extension}}
+ }
+}
Modified: cfe/trunk/test/SemaCXX/auto-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/auto-cxx0x.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/auto-cxx0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/auto-cxx0x.cpp Sun Sep 4 14:54:14 2011
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
void f() {
- auto int a; // expected-warning {{'auto' storage class specifier is redundant and will be removed in future releases}}
+ auto int a; // expected-warning {{'auto' storage class specifier is not permitted in C++0x, and will not be supported in future releases}}
int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}}
}
Modified: cfe/trunk/test/SemaCXX/auto-cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/auto-cxx98.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/auto-cxx98.cpp (original)
+++ cfe/trunk/test/SemaCXX/auto-cxx98.cpp Sun Sep 4 14:54:14 2011
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
void f() {
- auto int a;
- int auto b;
+ auto int a; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++0x}}
+ int auto b; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++0x}}
+ auto c; // expected-warning {{C++0x extension}} expected-error {{requires an initializer}}
+ static auto d = 0; // expected-warning {{C++0x extension}}
+ auto static e = 0; // expected-warning {{C++0x extension}}
}
Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=139102&r1=139101&r2=139102&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Sun Sep 4 14:54:14 2011
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
class C {
public:
- auto int errx; // expected-error {{error: storage class specified for a member declaration}}
+ auto int errx; // expected-error {{error: storage class specified for a member declaration}} expected-warning {{'auto' storage class specifier is redundant}}
register int erry; // expected-error {{error: storage class specified for a member declaration}}
extern int errz; // expected-error {{error: storage class specified for a member declaration}}
More information about the cfe-commits
mailing list