Skip to content

Commit 4d0bc2c

Browse files
committed
check type attribute arguments as well
1 parent 8b52d23 commit 4d0bc2c

File tree

4 files changed

+28
-30
lines changed

4 files changed

+28
-30
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13868,6 +13868,11 @@ class Sema final {
1386813868
SourceLocation BuiltinLoc,
1386913869
SourceLocation RParenLoc);
1387013870

13871+
void checkAttrArgsAreCapabilityObjs(Decl *D, const ParsedAttr &AL,
13872+
SmallVectorImpl<Expr *> &Args,
13873+
unsigned Sidx = 0,
13874+
bool ParamIdxOk = false);
13875+
1387113876
private:
1387213877
bool SemaBuiltinPrefetch(CallExpr *TheCall);
1387313878
bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall);

clang/lib/AST/TypePrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
18941894
case attr::ArmMveStrictPolymorphism:
18951895
OS << "__clang_arm_mve_strict_polymorphism";
18961896
break;
1897+
case attr::RequiresCapability:
1898+
OS << "requires_capability(blah)";
18971899
}
18981900
OS << "))";
18991901
}

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -600,12 +600,10 @@ static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
600600
/// \param Sidx The attribute argument index to start checking with.
601601
/// \param ParamIdxOk Whether an argument can be indexing into a function
602602
/// parameter list.
603-
static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
604-
const ParsedAttr &AL,
605-
SmallVectorImpl<Expr *> &Args,
606-
unsigned Sidx = 0,
607-
bool ParamIdxOk = false) {
608-
if (Sidx == AL.getNumArgs()) {
603+
void Sema::checkAttrArgsAreCapabilityObjs(Decl *D, const ParsedAttr &AL,
604+
SmallVectorImpl<Expr *> &Args,
605+
unsigned Sidx, bool ParamIdxOk) {
606+
if (D && Sidx == AL.getNumArgs()) {
609607
// If we don't have any capability arguments, the attribute implicitly
610608
// refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
611609
// a non-static method, and that the class is a (scoped) capability.
@@ -615,11 +613,10 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
615613
// FIXME -- need to check this again on template instantiation
616614
if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
617615
!checkRecordDeclForAttr<ScopedLockableAttr>(RD))
618-
S.Diag(AL.getLoc(),
619-
diag::warn_thread_attribute_not_on_capability_member)
616+
Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_capability_member)
620617
<< AL << MD->getParent();
621618
} else {
622-
S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
619+
Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
623620
<< AL;
624621
}
625622
}
@@ -644,7 +641,7 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
644641

645642
// We allow constant strings to be used as a placeholder for expressions
646643
// that are not valid C++ syntax, but warn that they are ignored.
647-
S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
644+
Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
648645
Args.push_back(ArgExp);
649646
continue;
650647
}
@@ -663,7 +660,7 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
663660
const RecordType *RT = getRecordType(ArgTy);
664661

665662
// Now check if we index into a record type function param.
666-
if(!RT && ParamIdxOk) {
663+
if (D && !RT && ParamIdxOk) {
667664
const auto *FD = dyn_cast<FunctionDecl>(D);
668665
const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
669666
if(FD && IL) {
@@ -672,8 +669,8 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
672669
uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
673670
uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
674671
if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
675-
S.Diag(AL.getLoc(),
676-
diag::err_attribute_argument_out_of_bounds_extra_info)
672+
Diag(AL.getLoc(),
673+
diag::err_attribute_argument_out_of_bounds_extra_info)
677674
<< AL << Idx + 1 << NumParams;
678675
continue;
679676
}
@@ -685,8 +682,8 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
685682
// expression have capabilities. This allows for writing C code where the
686683
// capability may be on the type, and the expression is a capability
687684
// boolean logic expression. Eg) requires_capability(A || B && !C)
688-
if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
689-
S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
685+
if (!typeHasCapability(*this, ArgTy) && !isCapabilityExpr(*this, ArgExp))
686+
Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
690687
<< AL << ArgTy;
691688

692689
Args.push_back(ArgExp);
@@ -708,7 +705,7 @@ static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
708705
Expr *&Arg) {
709706
SmallVector<Expr *, 1> Args;
710707
// check that all arguments are lockable objects
711-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
708+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args);
712709
unsigned Size = Args.size();
713710
if (Size != 1)
714711
return false;
@@ -750,7 +747,7 @@ static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
750747
}
751748

752749
// Check that all arguments are lockable objects.
753-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
750+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args);
754751
if (Args.empty())
755752
return false;
756753

@@ -781,7 +778,7 @@ static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
781778
SmallVectorImpl<Expr *> &Args) {
782779
// zero or more arguments ok
783780
// check that all arguments are lockable objects
784-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
781+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args, 0, /*ParamIdxOk=*/true);
785782

786783
return true;
787784
}
@@ -883,7 +880,7 @@ static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
883880
}
884881

885882
// check that all arguments are lockable objects
886-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
883+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args, 1);
887884

888885
return true;
889886
}
@@ -911,7 +908,7 @@ static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
911908
static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
912909
// check that the argument is lockable object
913910
SmallVector<Expr*, 1> Args;
914-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
911+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args);
915912
unsigned Size = Args.size();
916913
if (Size == 0)
917914
return;
@@ -925,7 +922,7 @@ static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
925922

926923
// check that all arguments are lockable objects
927924
SmallVector<Expr*, 1> Args;
928-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
925+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args);
929926
unsigned Size = Args.size();
930927
if (Size == 0)
931928
return;
@@ -8176,7 +8173,7 @@ static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
81768173
const ParsedAttr &AL) {
81778174
// Check that all arguments are lockable objects.
81788175
SmallVector<Expr *, 1> Args;
8179-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
8176+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args, 0, true);
81808177

81818178
D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
81828179
Args.size()));
@@ -8189,7 +8186,7 @@ static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
81898186

81908187
// check that all arguments are lockable objects
81918188
SmallVector<Expr*, 1> Args;
8192-
checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
8189+
S.checkAttrArgsAreCapabilityObjs(D, AL, Args);
81938190
if (Args.empty())
81948191
return;
81958192

clang/lib/Sema/SemaType.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8652,15 +8652,9 @@ static void HandleRequiresCapabilityAttr(TypeProcessingState &State,
86528652
return;
86538653
}
86548654

8655-
// FIXME: We need to sanity check the arguments here I think? Like we do in
8656-
// SemaDeclAtr.cpp.
8657-
86588655
llvm::SmallVector<Expr *, 4> Args;
86598656
Args.reserve(PA.getNumArgs() - 1);
8660-
for (unsigned Idx = 1; Idx < PA.getNumArgs(); Idx++) {
8661-
assert(!PA.isArgIdent(Idx));
8662-
Args.push_back(PA.getArgAsExpr(Idx));
8663-
}
8657+
State.getSema().checkAttrArgsAreCapabilityObjs(/*Decl=*/nullptr, PA, Args);
86648658

86658659
auto *RCAttr =
86668660
RequiresCapabilityAttr::Create(S.Context, Args.data(), Args.size(), PA);

0 commit comments

Comments
 (0)