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

via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 28 06:14:48 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy

Author: Balázs Kéri (balazske)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/194613.diff


4 Files Affected:

- (modified) clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp (+30-4) 
- (modified) clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h (+1-1) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5) 
- (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/random-generator-seed.cpp (+13) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp
index 3e32e9b8a704c..8fed18da7c220 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) {
+  clang::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 caf0275035064..cc7f3bc831800 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -260,6 +260,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]
+};

``````````

</details>


https://github.com/llvm/llvm-project/pull/194613


More information about the cfe-commits mailing list