r198956 - Downgrade bogus ExtWarn on duplicate 'friend' specifier to a Warning, and add a
Richard Smith
richard-llvm at metafoo.co.uk
Fri Jan 10 13:27:56 PST 2014
Author: rsmith
Date: Fri Jan 10 15:27:55 2014
New Revision: 198956
URL: http://llvm.org/viewvc/llvm-project?rev=198956&view=rev
Log:
Downgrade bogus ExtWarn on duplicate 'friend' specifier to a Warning, and add a
Warning for a duplicate 'constexpr' specifier.
Modified:
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/test/Parser/cxx-decl.cpp
cfe/trunk/test/Parser/cxx0x-decl.cpp
Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=198956&r1=198955&r2=198956&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Fri Jan 10 15:27:55 2014
@@ -827,7 +827,12 @@ bool DeclSpec::SetFriendSpec(SourceLocat
unsigned &DiagID) {
if (Friend_specified) {
PrevSpec = "friend";
- DiagID = diag::ext_duplicate_declspec;
+ // Keep the later location, so that we can later diagnose ill-formed
+ // declarations like 'friend class X friend;'. Per [class.friend]p3,
+ // 'friend' must be the first token in a friend declaration that is
+ // not a function declaration.
+ FriendLoc = Loc;
+ DiagID = diag::warn_duplicate_declspec;
return true;
}
@@ -850,7 +855,13 @@ bool DeclSpec::setModulePrivateSpec(Sour
bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID) {
- // 'constexpr constexpr' is ok.
+ // 'constexpr constexpr' is ok, but warn as this is likely not what the user
+ // intended.
+ if (Constexpr_specified) {
+ DiagID = diag::warn_duplicate_declspec;
+ PrevSpec = "constexpr";
+ return true;
+ }
Constexpr_specified = true;
ConstexprLoc = Loc;
return false;
Modified: cfe/trunk/test/Parser/cxx-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-decl.cpp?rev=198956&r1=198955&r2=198956&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-decl.cpp Fri Jan 10 15:27:55 2014
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic -fcxx-exceptions -fexceptions %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic-errors -fcxx-exceptions -fexceptions %s
-const char const *x10; // expected-warning {{duplicate 'const' declaration specifier}}
+const char const *x10; // expected-error {{duplicate 'const' declaration specifier}}
int x(*g); // expected-error {{use of undeclared identifier 'g'}}
@@ -46,7 +46,7 @@ class asm_class_test {
void foo() __asm__("baz");
};
-enum { fooenum = 1, }; // expected-warning {{commas at the end of enumerator lists are a C++11 extension}}
+enum { fooenum = 1, }; // expected-error {{commas at the end of enumerator lists are a C++11 extension}}
struct a {
int Type : fooenum;
@@ -81,7 +81,7 @@ namespace Commas {
(global5),
*global6,
&global7 = global1,
- &&global8 = static_cast<int&&>(global1), // expected-warning 2{{rvalue reference}}
+ &&global8 = static_cast<int&&>(global1), // expected-error 2{{rvalue reference}}
S::a,
global9,
global10 = 0,
@@ -212,14 +212,14 @@ namespace PR5066 {
template<typename T> struct X {};
X<int N> x; // expected-error {{type-id cannot have a name}}
- using T = int (*T)(); // expected-error {{type-id cannot have a name}} expected-warning {{C++11}}
+ using T = int (*T)(); // expected-error {{type-id cannot have a name}} expected-error {{C++11}}
}
namespace PR17255 {
void foo() {
typename A::template B<>; // expected-error {{use of undeclared identifier 'A'}} \
// expected-error {{expected a qualified name after 'typename'}} \
- // expected-warning {{'template' keyword outside of a template}}
+ // expected-error {{'template' keyword outside of a template}}
}
}
@@ -232,6 +232,13 @@ namespace PR17567 {
FooBar::~FooBar() {} // expected-error {{undeclared}} expected-error {{expected the class name}}
}
+namespace DuplicateFriend {
+ struct A {
+ friend void friend f(); // expected-warning {{duplicate 'friend' declaration specifier}}
+ friend struct B friend; // expected-warning {{duplicate 'friend' declaration specifier}}
+ };
+}
+
// PR8380
extern "" // expected-error {{unknown linkage language}}
test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \
Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=198956&r1=198955&r2=198956&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-decl.cpp Fri Jan 10 15:27:55 2014
@@ -104,3 +104,14 @@ namespace UsingDeclAttrs {
using [[gnu::aligned(1)]] T = int; // expected-error {{an attribute list cannot appear here}}
using T = int [[gnu::aligned(1)]]; // expected-error {{'aligned' attribute cannot be applied to types}}
}
+
+namespace DuplicateSpecifier {
+ constexpr constexpr int f(); // expected-warning {{duplicate 'constexpr' declaration specifier}}
+ constexpr int constexpr a = 0; // expected-warning {{duplicate 'constexpr' declaration specifier}}
+
+ struct A {
+ friend constexpr int constexpr friend f(); // expected-warning {{duplicate 'friend' declaration specifier}} \
+ // expected-warning {{duplicate 'constexpr' declaration specifier}}
+ friend struct A friend; // expected-warning {{duplicate 'friend'}} expected-error {{'friend' must appear first}}
+ };
+}
More information about the cfe-commits
mailing list