diff options
author | Aaron Puchert <aaronpuchert@alice-dsl.net> | 2020-10-28 23:23:09 +0100 |
---|---|---|
committer | Aaron Puchert <aaronpuchert@alice-dsl.net> | 2020-10-28 23:32:57 +0100 |
commit | 5dbccc6c89c0f6c6dc6277cc304057f6d50b298d (patch) | |
tree | 228794223f34ce102f4c6b8dc9258f1b01bcca04 | |
parent | 51f8d46491c7efd4e2054b036c13ef6266fceab3 (diff) | |
download | llvm-5dbccc6c89c0f6c6dc6277cc304057f6d50b298d.zip llvm-5dbccc6c89c0f6c6dc6277cc304057f6d50b298d.tar.gz llvm-5dbccc6c89c0f6c6dc6277cc304057f6d50b298d.tar.bz2 |
Better source location for -Wignored-qualifiers on trailing return types
We collect the source location of a trailing return type in the parser,
improving the location for regular functions and providing a location
for lambdas, where previously there was none.
Fixes PR47732.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D90129
-rw-r--r-- | clang/include/clang/Sema/DeclSpec.h | 11 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/return.cpp | 9 |
7 files changed, 32 insertions, 9 deletions
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 93a9126..33b57db 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -1363,6 +1363,10 @@ struct DeclaratorChunk { /// type specified. UnionParsedType TrailingReturnType; + /// If HasTrailingReturnType is true, this is the location of the trailing + /// return type. + unsigned TrailingReturnTypeLoc; + /// Reset the parameter list to having zero parameters. /// /// This is used in various places for error recovery. @@ -1499,6 +1503,11 @@ struct DeclaratorChunk { /// Get the trailing-return-type for this function declarator. ParsedType getTrailingReturnType() const { return TrailingReturnType; } + + /// Get the trailing-return-type location for this function declarator. + SourceLocation getTrailingReturnTypeLoc() const { + return SourceLocation::getFromRawEncoding(TrailingReturnTypeLoc); + } }; struct BlockPointerTypeInfo { @@ -1633,6 +1642,8 @@ struct DeclaratorChunk { Declarator &TheDeclarator, TypeResult TrailingReturnType = TypeResult(), + SourceLocation TrailingReturnTypeLoc = + SourceLocation(), DeclSpec *MethodQualifiers = nullptr); /// Return a DeclaratorChunk for a block. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 01a1657..281cd6d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -6429,6 +6429,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, CachedTokens *ExceptionSpecTokens = nullptr; ParsedAttributesWithRange FnAttrs(AttrFactory); TypeResult TrailingReturnType; + SourceLocation TrailingReturnTypeLoc; /* LocalEndLoc is the end location for the local FunctionTypeLoc. EndLoc is the end location for the function declarator. @@ -6539,6 +6540,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, SourceRange Range; TrailingReturnType = ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit()); + TrailingReturnTypeLoc = Range.getBegin(); EndLoc = Range.getEnd(); } } else if (standardAttributesAllowed()) { @@ -6571,7 +6573,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D, DynamicExceptionRanges.data(), DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, ExceptionSpecTokens, DeclsInPrototype, StartLoc, - LocalEndLoc, D, TrailingReturnType, &DS), + LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc, + &DS), std::move(FnAttrs), EndLoc); } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index a903896..6e9eced 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3898,6 +3898,7 @@ void Parser::ParseTrailingRequiresClause(Declarator &D) { auto &FunctionChunk = D.getFunctionTypeInfo(); FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable(); FunctionChunk.TrailingReturnType = TrailingReturnType.get(); + FunctionChunk.TrailingReturnTypeLoc = Range.getBegin().getRawEncoding(); } else SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma}, StopAtSemi | StopBeforeMatch); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index b225bb7..8181d2a 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1293,6 +1293,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( } TypeResult TrailingReturnType; + SourceLocation TrailingReturnTypeLoc; if (Tok.is(tok::l_paren)) { ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | @@ -1379,6 +1380,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( SourceRange Range; TrailingReturnType = ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); + TrailingReturnTypeLoc = Range.getBegin(); if (Range.getEnd().isValid()) DeclEndLoc = Range.getEnd(); } @@ -1395,7 +1397,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, /*ExceptionSpecTokens*/ nullptr, /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, - TrailingReturnType, &DS), + TrailingReturnType, TrailingReturnTypeLoc, &DS), std::move(Attr), DeclEndLoc); // Parse requires-clause[opt]. diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index dc37474..b139855 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -181,6 +181,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType, + SourceLocation + TrailingReturnTypeLoc, DeclSpec *MethodQualifiers) { assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) && "function cannot have _Atomic qualifier"); @@ -210,6 +212,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || TrailingReturnType.isInvalid(); I.Fun.TrailingReturnType = TrailingReturnType.get(); + I.Fun.TrailingReturnTypeLoc = TrailingReturnTypeLoc.getRawEncoding(); I.Fun.MethodQualifiers = nullptr; I.Fun.QualAttrFactory = nullptr; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1ba1869..21aa208 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3084,12 +3084,12 @@ void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy, Declarator &D, unsigned FunctionChunkIndex) { - if (D.getTypeObject(FunctionChunkIndex).Fun.hasTrailingReturnType()) { - // FIXME: TypeSourceInfo doesn't preserve location information for - // qualifiers. + const DeclaratorChunk::FunctionTypeInfo &FTI = + D.getTypeObject(FunctionChunkIndex).Fun; + if (FTI.hasTrailingReturnType()) { S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type, RetTy.getLocalCVRQualifiers(), - D.getIdentifierLoc()); + FTI.getTrailingReturnTypeLoc()); return; } diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp index 1550d00..ef45e61 100644 --- a/clang/test/SemaCXX/return.cpp +++ b/clang/test/SemaCXX/return.cpp @@ -61,9 +61,12 @@ _Atomic // expected-warning {{'_Atomic' type qualifier on return type has no eff int atomic(); -auto - trailing_return_type() -> // expected-warning {{'const' type qualifier on return type has no effect}} - const int; +auto trailing_return_type() -> + const int; // expected-warning {{'const' type qualifier on return type has no effect}} + +auto trailing_return_type_lambda = [](const int &x) -> + const int // expected-warning {{'const' type qualifier on return type has no effect}} + { return x; }; const int ret_array()[4]; // expected-error {{cannot return array}} } |