зеркало из https://github.com/microsoft/clang.git
Ignore const/volatile/restrict qualifiers on anonymous structs and
unions. Fixes PR8326. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131109 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4b7e048970
Коммит
7604f64a86
|
@ -758,7 +758,9 @@ def err_static_data_member_not_allowed_in_union_or_anon_struct : Error<
|
|||
"static data member %0 not allowed in %select{anonymous struct|union}1">;
|
||||
def err_union_member_of_reference_type : Error<
|
||||
"union member %0 has reference type %1">;
|
||||
|
||||
def ext_anonymous_struct_union_qualified : Extension<
|
||||
"anonymous %select{struct|union}0 cannot be '%select{const|volatile|"
|
||||
"restrict}1'">;
|
||||
def err_different_return_type_for_overriding_virtual_function : Error<
|
||||
"virtual function %0 has a different return type (%1) than the "
|
||||
"function it overrides (which has return type %2)">;
|
||||
|
|
|
@ -462,6 +462,14 @@ public:
|
|||
SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
|
||||
SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
|
||||
|
||||
/// \brief Clear out all of the type qualifiers.
|
||||
void ClearTypeQualifiers() {
|
||||
TypeQualifiers = 0;
|
||||
TQ_constLoc = SourceLocation();
|
||||
TQ_restrictLoc = SourceLocation();
|
||||
TQ_volatileLoc = SourceLocation();
|
||||
}
|
||||
|
||||
// function-specifier
|
||||
bool isInlineSpecified() const { return FS_inline_specified; }
|
||||
SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
|
||||
|
|
|
@ -2489,6 +2489,24 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
PrevSpec, DiagID, getLangOptions());
|
||||
}
|
||||
|
||||
// Ignore const/volatile/restrict qualifiers.
|
||||
if (DS.getTypeQualifiers()) {
|
||||
if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
|
||||
Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified)
|
||||
<< Record->isUnion() << 0
|
||||
<< FixItHint::CreateRemoval(DS.getConstSpecLoc());
|
||||
if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
|
||||
Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified)
|
||||
<< Record->isUnion() << 1
|
||||
<< FixItHint::CreateRemoval(DS.getVolatileSpecLoc());
|
||||
if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
|
||||
Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified)
|
||||
<< Record->isUnion() << 2
|
||||
<< FixItHint::CreateRemoval(DS.getRestrictSpecLoc());
|
||||
|
||||
DS.ClearTypeQualifiers();
|
||||
}
|
||||
|
||||
// C++ [class.union]p2:
|
||||
// The member-specification of an anonymous union shall only
|
||||
// define non-static data members. [Note: nested types and
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
|
||||
struct X {
|
||||
union {
|
||||
float f3;
|
||||
|
@ -17,7 +17,7 @@ struct X {
|
|||
|
||||
void test_unqual_references();
|
||||
|
||||
struct {
|
||||
struct { // expected-warning{{anonymous structs are a GNU extension}}
|
||||
int a;
|
||||
float b;
|
||||
};
|
||||
|
@ -125,7 +125,7 @@ typedef struct _s {
|
|||
// <rdar://problem/7987650>
|
||||
namespace test4 {
|
||||
class A {
|
||||
struct {
|
||||
struct { // expected-warning{{anonymous structs are a GNU extension}}
|
||||
int s0; // expected-note {{declared private here}}
|
||||
double s1; // expected-note {{declared private here}}
|
||||
union {
|
||||
|
@ -136,7 +136,7 @@ namespace test4 {
|
|||
union {
|
||||
int u0; // expected-note {{declared private here}}
|
||||
double u1; // expected-note {{declared private here}}
|
||||
struct {
|
||||
struct { // expected-warning{{anonymous structs are a GNU extension}}
|
||||
int us0; // expected-note {{declared private here}}
|
||||
double us1; // expected-note {{declared private here}}
|
||||
};
|
||||
|
@ -175,3 +175,25 @@ void foo_PR6741() {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR8326 {
|
||||
template <class T>
|
||||
class Foo {
|
||||
public:
|
||||
Foo()
|
||||
: x(0)
|
||||
, y(1){
|
||||
}
|
||||
|
||||
private:
|
||||
const union { // expected-warning{{anonymous union cannot be 'const'}}
|
||||
struct { // expected-warning{{anonymous structs are a GNU extension}}
|
||||
T x;
|
||||
T y;
|
||||
};
|
||||
T v[2];
|
||||
};
|
||||
};
|
||||
|
||||
Foo<int> baz;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче