diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 13 |
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; } |