diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 6fe78cd466f..aa0863e0e8c 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -734,6 +734,7 @@ static void diagnoseAndRemoveTypeQualifiers(Sema &S, const DeclSpec &DS, // it; they probably didn't mean to specify a redundant qualifier. typedef std::pair<DeclSpec::TQ, SourceLocation> QualLoc; for (QualLoc Qual : {QualLoc(DeclSpec::TQ_const, DS.getConstSpecLoc()), + QualLoc(DeclSpec::TQ_restrict, DS.getRestrictSpecLoc()), QualLoc(DeclSpec::TQ_volatile, DS.getVolatileSpecLoc()), QualLoc(DeclSpec::TQ_atomic, DS.getAtomicSpecLoc())}) { if (!(RemoveTQs & Qual.first)) @@ -750,6 +751,47 @@ static void diagnoseAndRemoveTypeQualifiers(Sema &S, const DeclSpec &DS, } } +/// Return true if this is omitted block return type. Also check type +/// attributes and type qualifiers when returning true. +static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator, + QualType Result) { + if (!isOmittedBlockReturnType(declarator)) + return false; + + // Warn if we see type attributes for omitted return type on a block literal. + AttributeList *&attrs = + declarator.getMutableDeclSpec().getAttributes().getListRef(); + AttributeList *prev = nullptr; + for (AttributeList *cur = attrs; cur; cur = cur->getNext()) { + AttributeList &attr = *cur; + // Skip attributes that were marked to be invalid or non-type + // attributes. + if (attr.isInvalid() || !attr.isTypeAttr()) { + prev = cur; + continue; + } + S.Diag(attr.getLoc(), + diag::warn_block_literal_attributes_on_omitted_return_type) + << attr.getName(); + // Remove cur from the list. + if (prev) { + prev->setNext(cur->getNext()); + prev = cur; + } else { + attrs = cur->getNext(); + } + } + + // Warn if we see type qualifiers for omitted return type on a block literal. + const DeclSpec &DS = declarator.getDeclSpec(); + unsigned TypeQuals = DS.getTypeQualifiers(); + diagnoseAndRemoveTypeQualifiers(S, DS, TypeQuals, Result, (unsigned)-1, + diag::warn_block_literal_qualifiers_on_omitted_return_type); + declarator.getMutableDeclSpec().ClearTypeQualifiers(); + + return true; +} + /// Apply Objective-C type arguments to the given type. static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, ArrayRef<TypeSourceInfo *> typeArgs, @@ -1266,7 +1308,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.getAutoDeductType(); break; } else if (declarator.getContext() == Declarator::LambdaExprContext || - isOmittedBlockReturnType(declarator)) { + checkOmittedBlockReturnType(S, declarator, + Context.DependentTy)) { Result = Context.DependentTy; break; } |