summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-04-18 18:40:51 +0000
committerManman Ren <manman.ren@gmail.com>2016-04-18 18:40:51 +0000
commit99d133482f7c7534bf4af6c0c2666b44f5b03a5f (patch)
treed550b13c27f16508c33071c8ad5f30a34c599cc6 /clang/lib/Sema
parent7f0756cc1fc2a3591f69b498143022055f0d338e (diff)
downloadbcm5719-llvm-99d133482f7c7534bf4af6c0c2666b44f5b03a5f.tar.gz
bcm5719-llvm-99d133482f7c7534bf4af6c0c2666b44f5b03a5f.zip
Block: Fix a crash when we have type attributes or qualifiers with omitted
return type. Emit a warning instead of crashing in IR generation. rdar://22762981 Differential Revision: http://reviews.llvm.org/D18567 llvm-svn: 266648
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaType.cpp45
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;
}
OpenPOWER on IntegriCloud