aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Puchert <aaronpuchert@alice-dsl.net>2020-10-28 23:23:09 +0100
committerAaron Puchert <aaronpuchert@alice-dsl.net>2020-10-28 23:32:57 +0100
commit5dbccc6c89c0f6c6dc6277cc304057f6d50b298d (patch)
tree228794223f34ce102f4c6b8dc9258f1b01bcca04
parent51f8d46491c7efd4e2054b036c13ef6266fceab3 (diff)
downloadllvm-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.h11
-rw-r--r--clang/lib/Parse/ParseDecl.cpp5
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp1
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp4
-rw-r--r--clang/lib/Sema/DeclSpec.cpp3
-rw-r--r--clang/lib/Sema/SemaType.cpp8
-rw-r--r--clang/test/SemaCXX/return.cpp9
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}}
}