r201620 - PR13110: Add a -Wignored-qualifiers warning when ignoring a const, volatile, or
Arthur O'Dwyer
arthur.j.odwyer at gmail.com
Tue Feb 18 20:41:57 PST 2014
On Tue, Feb 18, 2014 at 7:28 PM, Rafael Espíndola
<rafael.espindola at gmail.com> wrote:
> Looks like this fires quiet a bit in llvm itself:
>
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/6821/steps/build%2064-bit%20llvm%20using%20clang/logs/stdio
Looks like all nine of the warnings are triggered by this single line
in "llvm/include/llvm/Support/ErrorOr.h" —
const reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
— which is EXACTLY the case I was hoping would get caught by this
diagnostic! Awesome! :) Here, `const reference` should presumably
read `const_reference`. (Assuming there's a member typedef by that
name, that is. I bet there is.)
–Arthur
>
> On 18 February 2014 19:13, Richard Smith <richard-llvm at metafoo.co.uk> wrote:
>> Author: rsmith
>> Date: Tue Feb 18 18:13:27 2014
>> New Revision: 201620
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=201620&view=rev
>> Log:
>> PR13110: Add a -Wignored-qualifiers warning when ignoring a const, volatile, or
>> _Atomic qualifier applied to a reference type.
>>
>> Modified:
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/lib/Sema/SemaType.cpp
>> cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
>> cfe/trunk/test/CXX/drs/dr1xx.cpp
>> cfe/trunk/test/Parser/cxx-reference.cpp
>> cfe/trunk/test/Parser/cxx0x-rvalue-reference.cpp
>> cfe/trunk/test/SemaCXX/references.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 18 18:13:27 2014
>> @@ -3787,6 +3787,9 @@ def warn_typecheck_negative_array_new_si
>> 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<
>>
>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaType.cpp Tue Feb 18 18:13:27 2014
>> @@ -1117,17 +1117,32 @@ static QualType ConvertDeclSpecToType(Ty
>> }
>> }
>>
>> - // 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
>>
>> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp (original)
>> +++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp Tue Feb 18 18:13:27 2014
>> @@ -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&&);
>>
>> Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/CXX/drs/dr1xx.cpp (original)
>> +++ cfe/trunk/test/CXX/drs/dr1xx.cpp Tue Feb 18 18:13:27 2014
>> @@ -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
>>
>> Modified: cfe/trunk/test/Parser/cxx-reference.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-reference.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/Parser/cxx-reference.cpp (original)
>> +++ cfe/trunk/test/Parser/cxx-reference.cpp Tue Feb 18 18:13:27 2014
>> @@ -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}}
>>
>> Modified: cfe/trunk/test/Parser/cxx0x-rvalue-reference.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-rvalue-reference.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/Parser/cxx0x-rvalue-reference.cpp (original)
>> +++ cfe/trunk/test/Parser/cxx0x-rvalue-reference.cpp Tue Feb 18 18:13:27 2014
>> @@ -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}}
>> }
>>
>>
>> Modified: cfe/trunk/test/SemaCXX/references.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/references.cpp?rev=201620&r1=201619&r2=201620&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/references.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/references.cpp Tue Feb 18 18:13:27 2014
>> @@ -85,9 +85,19 @@ void test8(int& const,// expected-error{
>> 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;
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list