summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2015-09-23 22:14:21 +0000
committerJohn McCall <rjmccall@apple.com>2015-09-23 22:14:21 +0000
commit6997525eaa8fa6ea09e6a8c7a33908e81544ef1f (patch)
tree1decae494592ba5218d515d64f5d37c14fe5756f /clang/lib/Sema
parentd209967a68dc11e255c9794d77340dce080a84e6 (diff)
downloadbcm5719-llvm-6997525eaa8fa6ea09e6a8c7a33908e81544ef1f.tar.gz
bcm5719-llvm-6997525eaa8fa6ea09e6a8c7a33908e81544ef1f.zip
Forbid qualifiers on ObjC generic parameters and arguments, but
silently ignore them on arguments when they're provided indirectly (.e.g behind a template argument or typedef). This is mostly just good language design --- specifying that a generic argument is __weak doesn't actually do anything --- but it also prevents assertions when trying to apply a different ownership qualifier. rdar://21612439 llvm-svn: 248436
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp50
-rw-r--r--clang/lib/Sema/SemaType.cpp35
2 files changed, 62 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index f42c4b7546c..7b9b9c148c1 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -638,20 +638,44 @@ DeclResult Sema::actOnObjCTypeParam(Scope *S,
typeBoundInfo = nullptr;
}
- // Type bounds cannot have explicit nullability.
+ // Type bounds cannot have qualifiers (even indirectly) or explicit
+ // nullability.
if (typeBoundInfo) {
- // Type arguments cannot explicitly specify nullability.
- if (auto nullability = AttributedType::stripOuterNullability(typeBound)) {
- // Look at the type location information to find the nullability
- // specifier so we can zap it.
- SourceLocation nullabilityLoc
- = typeBoundInfo->getTypeLoc().findNullabilityLoc();
- SourceLocation diagLoc
- = nullabilityLoc.isValid()? nullabilityLoc
- : typeBoundInfo->getTypeLoc().getLocStart();
- Diag(diagLoc, diag::err_type_param_bound_explicit_nullability)
- << paramName << typeBoundInfo->getType()
- << FixItHint::CreateRemoval(nullabilityLoc);
+ QualType typeBound = typeBoundInfo->getType();
+ TypeLoc qual = typeBoundInfo->getTypeLoc().findExplicitQualifierLoc();
+ if (qual || typeBound.hasQualifiers()) {
+ bool diagnosed = false;
+ SourceRange rangeToRemove;
+ if (qual) {
+ if (auto attr = qual.getAs<AttributedTypeLoc>()) {
+ rangeToRemove = attr.getLocalSourceRange();
+ if (attr.getTypePtr()->getImmediateNullability()) {
+ Diag(attr.getLocStart(),
+ diag::err_objc_type_param_bound_explicit_nullability)
+ << paramName << typeBound
+ << FixItHint::CreateRemoval(rangeToRemove);
+ diagnosed = true;
+ }
+ }
+ }
+
+ if (!diagnosed) {
+ Diag(qual ? qual.getLocStart()
+ : typeBoundInfo->getTypeLoc().getLocStart(),
+ diag::err_objc_type_param_bound_qualified)
+ << paramName << typeBound << typeBound.getQualifiers().getAsString()
+ << FixItHint::CreateRemoval(rangeToRemove);
+ }
+
+ // If the type bound has qualifiers other than CVR, we need to strip
+ // them or we'll probably assert later when trying to apply new
+ // qualifiers.
+ Qualifiers quals = typeBound.getQualifiers();
+ quals.removeCVRQualifiers();
+ if (!quals.empty()) {
+ typeBoundInfo =
+ Context.getTrivialTypeSourceInfo(typeBound.getUnqualifiedType());
+ }
}
}
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 73da718a813..96c51a94ebb 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -790,18 +790,33 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type,
TypeSourceInfo *typeArgInfo = typeArgs[i];
QualType typeArg = typeArgInfo->getType();
- // Type arguments cannot explicitly specify nullability.
- if (auto nullability = AttributedType::stripOuterNullability(typeArg)) {
- SourceLocation nullabilityLoc
- = typeArgInfo->getTypeLoc().findNullabilityLoc();
- SourceLocation diagLoc = nullabilityLoc.isValid()? nullabilityLoc
- : typeArgInfo->getTypeLoc().getLocStart();
- S.Diag(diagLoc,
- diag::err_type_arg_explicit_nullability)
- << typeArg
- << FixItHint::CreateRemoval(nullabilityLoc);
+ // Type arguments cannot have explicit qualifiers or nullability.
+ // We ignore indirect sources of these, e.g. behind typedefs or
+ // template arguments.
+ if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) {
+ bool diagnosed = false;
+ SourceRange rangeToRemove;
+ if (auto attr = qual.getAs<AttributedTypeLoc>()) {
+ rangeToRemove = attr.getLocalSourceRange();
+ if (attr.getTypePtr()->getImmediateNullability()) {
+ typeArg = attr.getTypePtr()->getModifiedType();
+ S.Diag(attr.getLocStart(),
+ diag::err_objc_type_arg_explicit_nullability)
+ << typeArg << FixItHint::CreateRemoval(rangeToRemove);
+ diagnosed = true;
+ }
+ }
+
+ if (!diagnosed) {
+ S.Diag(qual.getLocStart(), diag::err_objc_type_arg_qualified)
+ << typeArg << typeArg.getQualifiers().getAsString()
+ << FixItHint::CreateRemoval(rangeToRemove);
+ }
}
+ // Remove qualifiers even if they're non-local.
+ typeArg = typeArg.getUnqualifiedType();
+
finalTypeArgs.push_back(typeArg);
if (typeArg->getAs<PackExpansionType>())
OpenPOWER on IntegriCloud