[clang] Fix analyzer crash on 'StructuralValue' (PR #79764)

Andrey Ali Khan Bolshakov via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 28 10:27:19 PST 2024


https://github.com/bolshakov-a created https://github.com/llvm/llvm-project/pull/79764

`OpaqueValueExpr` doesn't necessarily contain a source expression. Particularly, after #78041, it is used to carry the type and the value kind of a non-type template argument of floating-point type or referring to a subobject (those are so called `StructuralValue` arguments).

This fixes #79575.

>From 2a0a46f9242e99a18670d38f638a649fe808e4dc Mon Sep 17 00:00:00 2001
From: Bolshakov <bolsh.andrey at yandex.ru>
Date: Sun, 28 Jan 2024 21:12:10 +0300
Subject: [PATCH] Fix analyzer crash on 'StructuralValue'

`OpaqueValueExpr` doesn't necessarily contain a source expression.
Particularly, after #78041, it is used to carry the type and the value
kind of a non-type template argument of floating-point type or referring
to a subobject (those are so called `StructuralValue` arguments).

This fixes #79575.
---
 clang/lib/StaticAnalyzer/Core/Environment.cpp |  9 ++++++---
 clang/test/Analysis/templates.cpp             | 13 +++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index 4f989ed59bee38c..c77b28bc48fd674 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -40,8 +40,12 @@ static const Expr *ignoreTransparentExprs(const Expr *E) {
 
   switch (E->getStmtClass()) {
   case Stmt::OpaqueValueExprClass:
-    E = cast<OpaqueValueExpr>(E)->getSourceExpr();
-    break;
+    if (const clang::Expr *SE = cast<OpaqueValueExpr>(E)->getSourceExpr()) {
+      E = SE;
+      break;
+    } else {
+      return E;
+    }
   case Stmt::ExprWithCleanupsClass:
     E = cast<ExprWithCleanups>(E)->getSubExpr();
     break;
@@ -98,7 +102,6 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
   case Stmt::CXXBindTemporaryExprClass:
   case Stmt::ExprWithCleanupsClass:
   case Stmt::GenericSelectionExprClass:
-  case Stmt::OpaqueValueExprClass:
   case Stmt::ConstantExprClass:
   case Stmt::ParenExprClass:
   case Stmt::SubstNonTypeTemplateParmExprClass:
diff --git a/clang/test/Analysis/templates.cpp b/clang/test/Analysis/templates.cpp
index 061c19fe7e04451..6da1821b70f26fa 100644
--- a/clang/test/Analysis/templates.cpp
+++ b/clang/test/Analysis/templates.cpp
@@ -68,3 +68,16 @@ namespace rdar13954714 {
   // force instantiation
   template void blockWithStatic<true>();
 }
+
+namespace structural_value_crash {
+  constexpr char abc[] = "abc";
+
+  template <const char* in>
+  void use_template_param() {
+    const char *p = in;
+  }
+
+  void force_instantiate() {
+    use_template_param<abc>();
+  }
+}



More information about the cfe-commits mailing list