[clang] [Serialization] Fix instantiated default arguments (PR #76473)

Jonas Hahnfeld via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 27 14:15:48 PST 2023


https://github.com/hahnjo created https://github.com/llvm/llvm-project/pull/76473

`ParmVarDecl::getDefaultArg()` strips the outermost `FullExpr`, such as `ExprWithCleanups`. This leads to an `llvm_unreachable` being executed with the added test `clang/test/Modules/pr68702.cpp`; instead use the more generic `VarDecl::getInit()` which also returns `FullExpr`'s.

Closes https://github.com/llvm/llvm-project/issues/68702

>From def58be1572162b4862e37ba983793e422208d38 Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld at cern.ch>
Date: Wed, 27 Dec 2023 23:10:13 +0100
Subject: [PATCH] [Serialization] Fix instantiated default arguments

ParmVarDecl::getDefaultArg() strips the outermost FullExpr, such as
ExprWithCleanups. This leads to an llvm_unreachable being executed
with the added test clang/test/Modules/pr68702.cpp; instead use the
more generic VarDecl::getInit() which also returns FullExpr's.

Closes https://github.com/llvm/llvm-project/issues/68702
---
 clang/lib/Serialization/ASTWriter.cpp |  6 ++-
 clang/test/Modules/pr68702.cpp        | 65 +++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Modules/pr68702.cpp

diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 78939bfd533ffa..b9f65dc6d452fc 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5293,8 +5293,10 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
         break;
 
       case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT:
-        Record.AddStmt(const_cast<Expr *>(
-            cast<ParmVarDecl>(Update.getDecl())->getDefaultArg()));
+        // Do not use ParmVarDecl::getDefaultArg(): It strips the outermost
+        // FullExpr, such as ExprWithCleanups.
+        Record.AddStmt(
+            const_cast<Expr *>(cast<ParmVarDecl>(Update.getDecl())->getInit()));
         break;
 
       case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER:
diff --git a/clang/test/Modules/pr68702.cpp b/clang/test/Modules/pr68702.cpp
new file mode 100644
index 00000000000000..d32f946910f4fb
--- /dev/null
+++ b/clang/test/Modules/pr68702.cpp
@@ -0,0 +1,65 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %t/main.cpp -o %t/main.o
+
+//--- V.h
+#ifndef V_H
+#define V_H
+
+class A {
+public:
+  constexpr A() { }
+  constexpr ~A() { }
+};
+
+template <typename T>
+class V {
+public:
+  V() = default;
+
+  constexpr V(int n, const A& a = A()) {}
+};
+
+#endif
+
+//--- inst1.h
+#include "V.h"
+
+static void inst1() {
+  V<int> v;
+}
+
+//--- inst2.h
+#include "V.h"
+
+static void inst2() {
+  V<int> v(100);
+}
+
+//--- module.modulemap
+module "M" {
+  export *
+  module "V.h" {
+    export *
+    header "V.h"
+  }
+  module "inst1.h" {
+    export *
+    header "inst1.h"
+  }
+}
+
+module "inst2.h" {
+  export *
+  header "inst2.h"
+}
+
+//--- main.cpp
+#include "V.h"
+#include "inst2.h"
+
+static void m() {
+  static V<int> v(100);
+}



More information about the cfe-commits mailing list