Skip to content

Commit 061f87f

Browse files
[Clang][Sema]:Fix musttail attribute on a function with not_tail_called attribute has no warning/error (#134465)
The error is emitted when a musttail call is made to a function marked with the not_tail_called attribute.Closes #133509
1 parent be4c99a commit 061f87f

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,8 @@ Improvements to Clang's diagnostics
356356
- Now correctly diagnose a tentative definition of an array with static
357357
storage duration in pedantic mode in C. (#GH50661)
358358

359+
- An error is now emitted when a ``musttail`` call is made to a function marked with the ``not_tail_called`` attribute. (#GH133509).
360+
359361
Improvements to Clang's time-trace
360362
----------------------------------
361363

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,8 @@ def note_musttail_mismatch : Note<
31723172
"|has type mismatch at %ordinal3 parameter"
31733173
"%diff{ (expected $ but has $)|}1,2"
31743174
"|has different return type%diff{ ($ expected but has $)|}1,2}0">;
3175+
def note_musttail_disabled_by_not_tail_called : Note<
3176+
"'not_tail_called' attribute prevents being called as a tail call">;
31753177
def err_musttail_callconv_mismatch : Error<
31763178
"cannot perform a tail call to function%select{| %1}0 because it uses an "
31773179
"incompatible calling convention">;

clang/lib/Sema/SemaStmt.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,13 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
717717
return false;
718718
}
719719

720+
if (const FunctionDecl *CalleeDecl = CE->getDirectCallee();
721+
CalleeDecl && CalleeDecl->hasAttr<NotTailCalledAttr>()) {
722+
Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << /*show-function-callee=*/true << CalleeDecl;
723+
Diag(CalleeDecl->getLocation(), diag::note_musttail_disabled_by_not_tail_called);
724+
return false;
725+
}
726+
720727
if (const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
721728
if (EWC->cleanupsHaveSideEffects()) {
722729
Diag(St->getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;

clang/test/Sema/attr-musttail.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 -verify -fsyntax-only %s
2+
3+
int __attribute__((not_tail_called)) foo1(int a) {// expected-note {{'not_tail_called' attribute prevents being called as a tail call}}
4+
return a + 1;
5+
}
6+
7+
8+
int foo2(int a) {
9+
[[clang::musttail]]
10+
return foo1(a); // expected-error {{cannot perform a tail call to function 'foo1' because its signature is incompatible with the calling function}}
11+
}
12+
13+
int main() {
14+
int result = foo2(10);
15+
return 0;
16+
}
17+

0 commit comments

Comments
 (0)