Skip to content

Commit 0417cd1

Browse files
dougsonosDoug WyattSirraide
authored
[Clang] FunctionEffects: Correctly navigate through array types in FunctionEffectsRef::get(). (#121525)
`FunctionEffectsRef::get()` is supposed to strip off layers of indirection (pointers/references, type sugar) to get to a `FunctionProtoType` (if any) and return its effects (if any). It wasn't correctly dealing with situations where the compiler implicitly converts an array to a pointer. --------- Co-authored-by: Doug Wyatt <[email protected]> Co-authored-by: Sirraide <[email protected]>
1 parent 8abbd76 commit 0417cd1

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

clang/include/clang/AST/Type.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8841,13 +8841,16 @@ void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
88418841
unsigned Scale);
88428842

88438843
inline FunctionEffectsRef FunctionEffectsRef::get(QualType QT) {
8844+
const Type *TypePtr = QT.getTypePtr();
88448845
while (true) {
8845-
QualType Pointee = QT->getPointeeType();
8846-
if (Pointee.isNull())
8846+
if (QualType Pointee = TypePtr->getPointeeType(); !Pointee.isNull())
8847+
TypePtr = Pointee.getTypePtr();
8848+
else if (TypePtr->isArrayType())
8849+
TypePtr = TypePtr->getBaseElementTypeUnsafe();
8850+
else
88478851
break;
8848-
QT = Pointee;
88498852
}
8850-
if (const auto *FPT = QT->getAs<FunctionProtoType>())
8853+
if (const auto *FPT = TypePtr->getAs<FunctionProtoType>())
88518854
return FPT->getFunctionEffects();
88528855
return {};
88538856
}

clang/test/Sema/attr-nonblocking-constraints.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -fblocks -fcxx-exceptions -std=c++20 -verify -Wfunction-effects %s
1+
// RUN: %clang_cc1 -fsyntax-only -fblocks -fcxx-exceptions -std=c++20 -verify -Wfunction-effects -Wno-vla-extension %s
22
// These are in a separate file because errors (e.g. incompatible attributes) currently prevent
33
// the FXAnalysis pass from running at all.
44

@@ -246,6 +246,23 @@ void PTMFTester::convert() [[clang::nonblocking]]
246246
(this->*mConvertFunc)();
247247
}
248248

249+
// Allow implicit conversion from array to pointer.
250+
void nb14(unsigned idx) [[clang::nonblocking]]
251+
{
252+
using FP = void (*)() [[clang::nonblocking]];
253+
using FPArray = FP[2];
254+
auto nb = +[]() [[clang::nonblocking]] {};
255+
256+
FPArray src{ nb, nullptr };
257+
FP f = src[idx]; // This should not generate a warning.
258+
259+
FP twoDim[2][2] = {};
260+
FP g = twoDim[1][1];
261+
262+
FP vla[idx];
263+
FP h = vla[0];
264+
}
265+
249266
// Block variables
250267
void nb17(void (^blk)() [[clang::nonblocking]]) [[clang::nonblocking]] {
251268
blk();

0 commit comments

Comments
 (0)