Skip to content

Commit ac0a538

Browse files
authored
Update nodiscard test (#8471)
This adds coverage of two uses missed in the original test. The first covers structs with nodiscard on the type declaration, the second covers selecting the method spelling of the attribute over the type attribute if both are present.
1 parent 8634ef1 commit ac0a538

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

tools/clang/lib/AST/Decl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,10 +2876,11 @@ bool FunctionDecl::hasUnusedResultAttr() const {
28762876
QualType RetType = getReturnType();
28772877
if (RetType->isRecordType()) {
28782878
const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
2879-
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(this);
2880-
if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() &&
2881-
!(MD && MD->getCorrespondingMethodInClass(Ret, true)))
2879+
// HLSL Change Begin - nodiscard on a type should apply to all methods, even
2880+
// if they are not marked nodiscard themselves. This is the C++17 behavior.
2881+
if (Ret && Ret->hasAttr<WarnUnusedResultAttr>())
28822882
return true;
2883+
// HLSL Change End
28832884
}
28842885
return hasAttr<WarnUnusedResultAttr>();
28852886
}
@@ -2891,7 +2892,8 @@ Attr *FunctionDecl::getNoDiscardAttr() const {
28912892
const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
28922893
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(this);
28932894
if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() &&
2894-
!(MD && MD->getCorrespondingMethodInClass(Ret, true)))
2895+
(!hasAttr<WarnUnusedResultAttr>() ||
2896+
!(MD && (MD->getCorrespondingMethodInClass(Ret, true)))))
28952897
return Ret->getAttr<WarnUnusedResultAttr>();
28962898
}
28972899
return getAttr<WarnUnusedResultAttr>();

tools/clang/test/SemaHLSL/attributes/nodiscard.hlsl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,29 @@ using MatrixATy = Matrix<ComponentType::F32, 4, 4, MatrixUse::A, MatrixScope::Wa
88
[nodiscard] int fn() { return 42; }
99
[[nodiscard]] int fn2() { return 42; }
1010

11+
struct [[nodiscard]] S {
12+
int x;
13+
14+
[[clang::warn_unused_result]] static S fn4() { return (S)42; }
15+
[[clang::warn_unused_result]] S fn5() { return (S)42; }
16+
17+
static S fn6() { return (S)42; }
18+
S fn7() { return (S)42; }
19+
};
20+
21+
S fn3() { return (S)42; }
22+
1123
[numthreads(4, 4, 4)]
1224
void main(uint ID : SV_GroupID)
1325
{
1426
MatrixATy MatA1;
1527
MatA1.Splat(1.0f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1628
fn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1729
fn2(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
30+
fn3(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
31+
S::fn4(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
32+
S s;
33+
s.fn5(); // expected-warning {{ignoring return value of function declared with 'warn_unused_result' attribute}}
34+
S::fn6(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
35+
s.fn7(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1836
}

0 commit comments

Comments
 (0)