Author: Balázs Kéri
Date: 2026-05-13T09:10:58+02:00
New Revision: b4b9b1fc498b5891efeabd25e055ba3f41a6da11

URL: 
https://github.com/llvm/llvm-project/commit/b4b9b1fc498b5891efeabd25e055ba3f41a6da11
DIFF: 
https://github.com/llvm/llvm-project/commit/b4b9b1fc498b5891efeabd25e055ba3f41a6da11.diff

LOG: [clang-tidy] Adding note of implicit initialization to 
'bugprone-random-generator-seed' (#194613)

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp
    clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h
    clang-tools-extra/docs/ReleaseNotes.rst
    
clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp

Removed: 
    


################################################################################
diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp
index 3e32e9b8a704c..270776e9899ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "RandomGeneratorSeedCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/STLExtras.h"
 
@@ -15,6 +16,22 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::bugprone {
 
+namespace {
+AST_MATCHER_P(CXXConstructExpr, hasImplicitCtorInitField,
+              ast_matchers::internal::Matcher<Decl>, InnerMatcher) {
+  const DynTypedNodeList Parents =
+      Finder->getASTContext().getParentMapContext().getParents(Node);
+  if (Parents.empty())
+    return false;
+  if (const auto *Ctor = Parents[0].get<CXXConstructorDecl>()) {
+    for (const CXXCtorInitializer *Init : Ctor->inits())
+      if (!Init->isWritten() && Init->getInit() == &Node && Init->getMember())
+        return InnerMatcher.matches(*Init->getMember(), Finder, Builder);
+  }
+  return false;
+}
+} // namespace
+
 RandomGeneratorSeedCheck::RandomGeneratorSeedCheck(StringRef Name,
                                                    ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
@@ -59,8 +76,10 @@ void RandomGeneratorSeedCheck::registerMatchers(MatchFinder 
*Finder) {
   // std::mt19937 engine(x);
   //              ^
   Finder->addMatcher(
-      traverse(TK_AsIs,
-               
cxxConstructExpr(RandomGeneratorEngineTypeMatcher).bind("ctor")),
+      traverse(TK_AsIs, cxxConstructExpr(RandomGeneratorEngineTypeMatcher,
+                                         optionally(hasImplicitCtorInitField(
+                                             fieldDecl().bind("field"))))
+                            .bind("ctor")),
       this);
 
   // srand();
@@ -77,7 +96,7 @@ void RandomGeneratorSeedCheck::registerMatchers(MatchFinder 
*Finder) {
 void RandomGeneratorSeedCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");
   if (Ctor)
-    checkSeed(Result, Ctor);
+    checkSeed(Result, Ctor, Result.Nodes.getNodeAs<FieldDecl>("field"));
 
   const auto *Func = Result.Nodes.getNodeAs<CXXMemberCallExpr>("seed");
   if (Func)
@@ -90,11 +109,18 @@ void RandomGeneratorSeedCheck::check(const 
MatchFinder::MatchResult &Result) {
 
 template <class T>
 void RandomGeneratorSeedCheck::checkSeed(const MatchFinder::MatchResult 
&Result,
-                                         const T *Func) {
+                                         const T *Func,
+                                         const FieldDecl *Field) {
   if (Func->getNumArgs() == 0 || Func->getArg(0)->isDefaultArgument()) {
     diag(Func->getExprLoc(),
          "random number generator seeded with a default argument will generate 
"
          "a predictable sequence of values");
+    if (Field)
+      diag(Field->getLocation(),
+           "field %0 is implicitly initialized with a default seed argument",
+           DiagnosticIDs::Note)
+          << Field;
+
     return;
   }
 

diff  --git a/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h 
b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h
index c9c54eaa14000..8085fed10ae05 100644
--- a/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h
@@ -31,7 +31,7 @@ class RandomGeneratorSeedCheck : public ClangTidyCheck {
 private:
   template <class T>
   void checkSeed(const ast_matchers::MatchFinder::MatchResult &Result,
-                 const T *Func);
+                 const T *Func, const FieldDecl *Field = nullptr);
 
   StringRef RawDisallowedSeedTypes;
   SmallVector<StringRef, 5> DisallowedSeedTypes;

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 3f000d7051614..48d920e8e291b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -370,6 +370,11 @@ Changes in existing checks
   <clang-tidy/checks/bugprone/pointer-arithmetic-on-polymorphic-object>` check
   by fixing a false positive when ``operator[]`` is used in a dependent 
context.
 
+- Improved :doc:`bugprone-random-generator-seed
+  <clang-tidy/checks/bugprone/random-generator-seed>` check by adding
+  a new note at the location of the field if the generator is implicitly
+  initialized with a default seed value.
+
 - Improved :doc:`bugprone-std-namespace-modification
   <clang-tidy/checks/bugprone/std-namespace-modification>` check by fixing
   false positives when extending the standard library with a specialization of

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp
index c8818d6770799..97cad30b2f5fe 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp
@@ -209,3 +209,16 @@ void g() {
   a1.seed(1);
   a1.seed(n);
 }
+
+struct B {
+  std::default_random_engine eng1;
+  std::default_random_engine eng2{1};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: random number generator seeded 
with a constant value will generate a predictable sequence of values 
[bugprone-random-generator-seed]
+  std::default_random_engine eng3;
+  std::default_random_engine eng4;
+  B() : eng3(1), eng4() { }
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded 
with a default argument will generate a predictable sequence of values 
[bugprone-random-generator-seed]
+  // CHECK-MESSAGES: :[[@LINE-7]]:30: note: field 'eng1' is implicitly 
initialized with a default seed argument
+  // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: random number generator seeded 
with a constant value will generate a predictable sequence of values 
[bugprone-random-generator-seed]
+  // CHECK-MESSAGES: :[[@LINE-4]]:18: warning: random number generator seeded 
with a default argument will generate a predictable sequence of values 
[bugprone-random-generator-seed]
+};


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to