mirror of https://github.com/microsoft/clang.git
PR13110: Add a -Wignored-qualifiers warning when ignoring a const, volatile, or
_Atomic qualifier applied to a reference type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201620 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
91e3d5860a
commit
d970a31d7c
|
@ -3787,6 +3787,9 @@ def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
|
|||
InGroup<BadArrayNewLength>;
|
||||
def warn_typecheck_function_qualifiers : Warning<
|
||||
"qualifier on function type %0 has unspecified behavior">;
|
||||
def warn_typecheck_reference_qualifiers : Warning<
|
||||
"'%0' qualifier on reference type %1 has no effect">,
|
||||
InGroup<IgnoredQualifiers>;
|
||||
def err_typecheck_invalid_restrict_not_pointer : Error<
|
||||
"restrict requires a pointer or reference (%0 is invalid)">;
|
||||
def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
|
||||
|
|
|
@ -1117,17 +1117,32 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
}
|
||||
}
|
||||
|
||||
// C++ [dcl.ref]p1:
|
||||
// C++11 [dcl.ref]p1:
|
||||
// Cv-qualified references are ill-formed except when the
|
||||
// cv-qualifiers are introduced through the use of a typedef
|
||||
// (7.1.3) or of a template type argument (14.3), in which
|
||||
// case the cv-qualifiers are ignored.
|
||||
// FIXME: Shouldn't we be checking SCS_typedef here?
|
||||
// cv-qualifiers are introduced through the use of a typedef-name
|
||||
// or decltype-specifier, in which case the cv-qualifiers are ignored.
|
||||
//
|
||||
// There don't appear to be any other contexts in which a cv-qualified
|
||||
// reference type could be formed, so the 'ill-formed' clause here appears
|
||||
// to never happen.
|
||||
if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
|
||||
TypeQuals && Result->isReferenceType()) {
|
||||
TypeQuals &= ~DeclSpec::TQ_const;
|
||||
TypeQuals &= ~DeclSpec::TQ_volatile;
|
||||
TypeQuals &= ~DeclSpec::TQ_atomic;
|
||||
// If this occurs outside a template instantiation, warn the user about
|
||||
// it; they probably didn't mean to specify a redundant qualifier.
|
||||
std::pair<DeclSpec::TQ, SourceLocation> Quals[] = {
|
||||
{ DeclSpec::TQ_const, DS.getConstSpecLoc() },
|
||||
{ DeclSpec::TQ_volatile, DS.getVolatileSpecLoc() },
|
||||
{ DeclSpec::TQ_atomic, DS.getAtomicSpecLoc() }
|
||||
};
|
||||
for (unsigned I = 0, N = llvm::array_lengthof(Quals); I != N; ++I) {
|
||||
if (S.ActiveTemplateInstantiations.empty()) {
|
||||
if (TypeQuals & Quals[I].first)
|
||||
S.Diag(Quals[I].second, diag::warn_typecheck_reference_qualifiers)
|
||||
<< DeclSpec::getSpecifierName(Quals[I].first) << Result
|
||||
<< FixItHint::CreateRemoval(Quals[I].second);
|
||||
}
|
||||
TypeQuals &= ~Quals[I].first;
|
||||
}
|
||||
}
|
||||
|
||||
// C90 6.5.3 constraints: "The same type qualifier shall not appear more
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_same {
|
||||
|
@ -20,8 +19,8 @@ typedef int& LRI;
|
|||
typedef int&& RRI;
|
||||
|
||||
typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&);
|
||||
typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&);
|
||||
typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&);
|
||||
typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}}
|
||||
typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}}
|
||||
|
||||
typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&);
|
||||
typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&);
|
||||
|
|
|
@ -40,13 +40,13 @@ namespace dr102 { // dr102: yes
|
|||
namespace dr106 { // dr106: sup 540
|
||||
typedef int &r1;
|
||||
typedef r1 &r1;
|
||||
typedef const r1 r1;
|
||||
typedef const r1 &r1;
|
||||
typedef const r1 r1; // expected-warning {{has no effect}}
|
||||
typedef const r1 &r1; // expected-warning {{has no effect}}
|
||||
|
||||
typedef const int &r2;
|
||||
typedef r2 &r2;
|
||||
typedef const r2 r2;
|
||||
typedef const r2 &r2;
|
||||
typedef const r2 r2; // expected-warning {{has no effect}}
|
||||
typedef const r2 &r2; // expected-warning {{has no effect}}
|
||||
}
|
||||
|
||||
namespace dr107 { // dr107: yes
|
||||
|
|
|
@ -10,7 +10,7 @@ void foo(int &a) {
|
|||
|
||||
typedef int & A;
|
||||
|
||||
void g(const A aref) {
|
||||
void g(const A aref) { // expected-warning {{'const' qualifier on reference type 'A' (aka 'int &') has no effect}}
|
||||
}
|
||||
|
||||
int & const X = val; // expected-error {{'const' qualifier may not be applied to a reference}}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
int && r1(int &&a);
|
||||
|
||||
typedef int && R;
|
||||
void r2(const R a) {
|
||||
void r2(const R a) { // expected-warning {{'const' qualifier on reference type 'R' (aka 'int &&') has no effect}}
|
||||
int & &&ar = a; // expected-error{{'ar' declared as a reference to a reference}}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,9 +85,19 @@ void test8(int& const,// expected-error{{'const' qualifier may not be applied to
|
|||
typedef int& intref;
|
||||
typedef intref& intrefref; // C++ DR 106: reference collapsing
|
||||
|
||||
typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref?
|
||||
typedef intref const intref_c; // expected-warning {{'const' qualifier on reference type 'intref' (aka 'int &') has no effect}}
|
||||
typedef intref_c intref; // ok, same type
|
||||
|
||||
typedef intref volatile intref; // expected-warning {{'volatile' qualifier on reference type 'intref' (aka 'int &') has no effect}}
|
||||
typedef intref _Atomic intref; // expected-warning {{'_Atomic' qualifier on reference type 'intref' (aka 'int &') has no effect}}
|
||||
|
||||
void restrict_ref(__restrict intref); // ok
|
||||
void restrict_ref(int &__restrict); // ok
|
||||
}
|
||||
|
||||
template<typename T> int const_param(const T) {}
|
||||
int const_ref_param = const_param<int&>(const_ref_param); // no-warning
|
||||
|
||||
|
||||
class string {
|
||||
char *Data;
|
||||
|
|
Loading…
Reference in New Issue