summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp19
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp13
2 files changed, 15 insertions, 17 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 702a2e32e3e..fdf94a8ad5e 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2691,17 +2691,20 @@ SourceRange FunctionDecl::getReturnTypeSourceRange() const {
const TypeSourceInfo *TSI = getTypeSourceInfo();
if (!TSI)
return SourceRange();
-
- TypeLoc TL = TSI->getTypeLoc();
- FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
- if (!FunctionTL)
+ FunctionTypeLoc FTL =
+ TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+ if (!FTL)
return SourceRange();
- TypeLoc ResultTL = FunctionTL.getReturnLoc();
- if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
- return ResultTL.getSourceRange();
+ // Skip self-referential return types.
+ const SourceManager &SM = getASTContext().getSourceManager();
+ SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+ SourceLocation Boundary = getNameInfo().getLocStart();
+ if (RTRange.isInvalid() || Boundary.isInvalid() ||
+ !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+ return SourceRange();
- return SourceRange();
+ return RTRange;
}
/// \brief For an inline function definition in C, or for a gnu_inline function
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index dcb6530552d..a1d1d0c4a58 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3029,16 +3029,11 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D,
static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
FunctionDecl *FD = cast<FunctionDecl>(D);
if (!FD->getReturnType()->isVoidType()) {
- TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
- if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
- S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
+ S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
<< FD->getType()
- << FixItHint::CreateReplacement(FTL.getReturnLoc().getSourceRange(),
- "void");
- } else {
- S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
- << FD->getType();
- }
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+ : FixItHint());
return;
}
OpenPOWER on IntegriCloud