Skip to content

Commit 21215a7

Browse files
authored
merge main into amd-staging (llvm#936)
2 parents 77f1902 + 59e00df commit 21215a7

File tree

48 files changed

+728
-394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+728
-394
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ Changes in existing checks
122122
- Improved :doc:`misc-const-correctness
123123
<clang-tidy/checks/misc/const-correctness>` check by adding the option
124124
`AllowedTypes`, that excludes specified types from const-correctness
125-
checking.
125+
checking and fixing false positives when modifying variant by ``operator[]``
126+
with template in parameters.
126127

127128
- Improved :doc:`misc-redundant-expression
128129
<clang-tidy/checks/misc/redundant-expression>` check by providing additional

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,3 +998,11 @@ void member_pointer_const(Value &x, PointerToConstMemberFunction m) {
998998
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'member_pointer_tmp' of type 'Value &' can be declared 'const'
999999
(member_pointer_tmp.*m)();
10001000
}
1001+
1002+
namespace gh127776_false_positive {
1003+
template <class T> struct vector { T &operator[](int t); };
1004+
template <typename T> void f() {
1005+
vector<int> x;
1006+
x[T{}] = 3;
1007+
}
1008+
} // namespace gh127776_false_positive

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ Non-comprehensive list of changes in this release
114114
New Compiler Flags
115115
------------------
116116

117+
- New option ``-Wundef-true`` added and enabled by default to warn when `true` is used in the C preprocessor without being defined before C23.
118+
117119
- New option ``-fprofile-continuous`` added to enable continuous profile syncing to file (#GH124353, `docs <https://clang.llvm.org/docs/UsersManual.html#cmdoption-fprofile-continuous>`_).
118120
The feature has `existed <https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program>`_)
119121
for a while and this is just a user facing option.

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,8 @@ def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", [ReservedIdAsMacro]>
791791
def ReservedAttributeIdentifier : DiagGroup<"reserved-attribute-identifier">;
792792
def RestrictExpansionMacro : DiagGroup<"restrict-expansion">;
793793
def FinalMacro : DiagGroup<"final-macro">;
794+
def UndefinedTrueIdentifier : DiagGroup<"undef-true">;
795+
def UndefinedIdentifier : DiagGroup<"undef", [UndefinedTrueIdentifier]>;
794796

795797
// Just silence warnings about -Wstrict-aliasing for now.
796798
def : DiagGroup<"strict-aliasing=0">;

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,10 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
392392
InGroup<DiagGroup<"unused-macros">>;
393393
def warn_pp_undef_identifier : Warning<
394394
"%0 is not defined, evaluates to 0">,
395-
InGroup<DiagGroup<"undef">>, DefaultIgnore;
395+
InGroup<UndefinedIdentifier>, DefaultIgnore;
396+
def warn_pp_undef_true_identifier : Warning<
397+
"'true' is not defined, evaluates to 0">,
398+
InGroup<UndefinedTrueIdentifier>;
396399
def warn_pp_undef_prefix : Warning<
397400
"%0 is not defined, evaluates to 0">,
398401
InGroup<DiagGroup<"undef-prefix">>, DefaultIgnore;

clang/lib/Analysis/ExprMutationAnalyzer.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ static bool canExprResolveTo(const Expr *Source, const Expr *Target) {
8080

8181
namespace {
8282

83+
// `ArraySubscriptExpr` can switch base and idx, e.g. `a[4]` is the same as
84+
// `4[a]`. When type is dependent, we conservatively assume both sides are base.
85+
AST_MATCHER_P(ArraySubscriptExpr, hasBaseConservative,
86+
ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
87+
if (Node.isTypeDependent()) {
88+
return InnerMatcher.matches(*Node.getLHS(), Finder, Builder) ||
89+
InnerMatcher.matches(*Node.getRHS(), Finder, Builder);
90+
}
91+
return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
92+
}
93+
8394
AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); }
8495

8596
AST_MATCHER_P(LambdaExpr, hasCaptureInit, const Expr *, E) {
@@ -513,8 +524,8 @@ ExprMutationAnalyzer::Analyzer::findArrayElementMutation(const Expr *Exp) {
513524
// Check whether any element of an array is mutated.
514525
const auto SubscriptExprs = match(
515526
findAll(arraySubscriptExpr(
516-
anyOf(hasBase(canResolveToExpr(Exp)),
517-
hasBase(implicitCastExpr(allOf(
527+
anyOf(hasBaseConservative(canResolveToExpr(Exp)),
528+
hasBaseConservative(implicitCastExpr(allOf(
518529
hasCastKind(CK_ArrayToPointerDecay),
519530
hasSourceExpression(canResolveToExpr(Exp)))))))
520531
.bind(NodeID<Expr>::value)),
@@ -716,7 +727,8 @@ ExprMutationAnalyzer::Analyzer::findPointeeValueMutation(const Expr *Exp) {
716727
unaryOperator(hasOperatorName("*"),
717728
hasUnaryOperand(canResolveToExprPointee(Exp))),
718729
// deref by []
719-
arraySubscriptExpr(hasBase(canResolveToExprPointee(Exp)))))
730+
arraySubscriptExpr(
731+
hasBaseConservative(canResolveToExprPointee(Exp)))))
720732
.bind(NodeID<Expr>::value))),
721733
Stm, Context);
722734
return findExprMutation(Matches);

clang/lib/Lex/PPExpressions.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
257257
// preprocessor keywords and it wasn't macro expanded, it turns
258258
// into a simple 0
259259
if (ValueLive) {
260-
PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
260+
unsigned DiagID = II->getName() == "true"
261+
? diag::warn_pp_undef_true_identifier
262+
: diag::warn_pp_undef_identifier;
263+
PP.Diag(PeekTok, DiagID) << II;
261264

262265
const DiagnosticsEngine &DiagEngine = PP.getDiagnostics();
263266
// If 'Wundef' is enabled, do not emit 'undef-prefix' diagnostics.
264-
if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier,
265-
PeekTok.getLocation())) {
267+
if (DiagEngine.isIgnored(DiagID, PeekTok.getLocation())) {
266268
const std::vector<std::string> UndefPrefixes =
267269
DiagEngine.getDiagnosticOptions().UndefPrefixes;
268270
const StringRef IdentifierName = II->getName();
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %clang_cc1 %s -Eonly -std=c89 -verify=undef-true
2+
// RUN: %clang_cc1 %s -Eonly -std=c99 -verify=undef-true
3+
// RUN: %clang_cc1 %s -Eonly -std=c11 -verify=undef-true
4+
// RUN: %clang_cc1 %s -Eonly -std=c17 -verify=undef-true
5+
// RUN: %clang_cc1 %s -Eonly -std=c23 -verify=undef-true
6+
7+
#if __STDC_VERSION__ >= 202311L
8+
/* undef-true-no-diagnostics */
9+
#endif
10+
11+
#define FOO true
12+
#if FOO /* #1 */
13+
#endif
14+
#if __STDC_VERSION__ < 202311L
15+
/* undef-true-warning@#1 {{'true' is not defined, evaluates to 0}} */
16+
#endif
17+
18+
#if true /* #2 */
19+
#endif
20+
#if __STDC_VERSION__ < 202311L
21+
/* undef-true-warning@#2 {{'true' is not defined, evaluates to 0}} */
22+
#endif
23+
24+
#if false || true /* #3 */
25+
#endif
26+
#if __STDC_VERSION__ < 202311L
27+
/* undef-true-warning@#3 {{'true' is not defined, evaluates to 0}} */
28+
#endif
29+
30+
#define true 1
31+
32+
#define FOO true
33+
#if FOO
34+
#endif
35+
36+
#if true
37+
#endif
38+
39+
#if false || true
40+
#endif
41+
42+
#undef true
43+
44+
#define FOO true
45+
#if FOO /* #4 */
46+
#endif
47+
#if __STDC_VERSION__ < 202311L
48+
/* undef-true-warning@#4 {{'true' is not defined, evaluates to 0}} */
49+
#endif
50+
51+
#if true /* #5 */
52+
#endif
53+
#if __STDC_VERSION__ < 202311L
54+
/* undef-true-warning@#5 {{'true' is not defined, evaluates to 0}} */
55+
#endif
56+
57+
#if false || true /* #6 */
58+
#endif
59+
#if __STDC_VERSION__ < 202311L
60+
/* undef-true-warning@#6 {{'true' is not defined, evaluates to 0}} */
61+
#endif
62+
63+
#define true true
64+
#if true /* #7 */
65+
#endif
66+
#if __STDC_VERSION__ < 202311L
67+
/* undef-true-warning@#7 {{'true' is not defined, evaluates to 0}} */
68+
#endif
69+
#undef true
70+
71+
/* Test that #pragma-enabled 'Wundef' can override 'Wundef-true' */
72+
#pragma clang diagnostic warning "-Wundef"
73+
#if true /* #8 */
74+
#endif
75+
#pragma clang diagnostic ignored "-Wundef"
76+
#if __STDC_VERSION__ < 202311L
77+
/* undef-true-warning@#8 {{'true' is not defined, evaluates to 0}} */
78+
#endif

clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,19 @@ TEST(ExprMutationAnalyzerTest, TemplateWithArrayToPointerDecay) {
870870
EXPECT_THAT(mutatedBy(ResultsY, AST.get()), ElementsAre("y"));
871871
}
872872

873+
TEST(ExprMutationAnalyzerTest, T1) {
874+
const auto AST = buildASTFromCodeWithArgs(
875+
"template <class T> struct vector { T &operator[](int t); };"
876+
"template <typename T> void func() {"
877+
" vector<int> x;"
878+
" x[T{}] = 3;"
879+
"}",
880+
{"-fno-delayed-template-parsing"});
881+
const auto Results =
882+
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
883+
EXPECT_TRUE(isMutated(Results, AST.get()));
884+
}
885+
873886
// section: special case: all created references are non-mutating themself
874887
// and therefore all become 'const'/the value is not modified!
875888

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"`LWG3973 <https://wg21.link/LWG3973>`__","Monadic operations should be ADL-proof","2023-11 (Kona)","","",""
3838
"`LWG3974 <https://wg21.link/LWG3974>`__","``mdspan::operator[]`` should not copy ``OtherIndexTypes``","2023-11 (Kona)","","",""
3939
"`LWG3987 <https://wg21.link/LWG3987>`__","Including ``<flat_foo>`` doesn't provide ``std::begin``/``end``","2023-11 (Kona)","","",""
40-
"`LWG3990 <https://wg21.link/LWG3990>`__","Program-defined specializations of ``std::tuple`` and ``std::variant`` can't be properly supported","2023-11 (Kona)","","",""
40+
"`LWG3990 <https://wg21.link/LWG3990>`__","Program-defined specializations of ``std::tuple`` and ``std::variant`` can't be properly supported","2023-11 (Kona)","|Complete|","21",""
4141
"`LWG4001 <https://wg21.link/LWG4001>`__","``iota_view`` should provide ``empty``","2023-11 (Kona)","|Complete|","19",""
4242
"","","","","",""
4343
"`LWG3767 <https://wg21.link/LWG3767>`__","``codecvt<charN_t, char8_t, mbstate_t>`` incorrectly added to locale","2024-03 (Tokyo)","","",""

0 commit comments

Comments
 (0)