[clang] 05137ec - [clang-repl] Emit const variables only once (#65257)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 3 02:58:27 PDT 2023


Author: Jonas Hahnfeld
Date: 2023-10-03T11:58:23+02:00
New Revision: 05137ecfca0bd2f7fa6cd30c771dfacbb8188785

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

LOG: [clang-repl] Emit const variables only once (#65257)

Disable internal linkage for const variables if IncrementalExtensions
are enabled. Otherwise the variables are emitted multiple times, with
multiple constructions at unique memory locations, during every PTU.

Added: 
    clang/test/Interpreter/const.cpp

Modified: 
    clang/lib/AST/ASTContext.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8917662c5336825..e3e4578ffd49e19 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -11768,6 +11768,16 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
 
 static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
                                              const VarDecl *VD) {
+  // As an extension for interactive REPLs, make sure constant variables are
+  // only emitted once instead of LinkageComputer::getLVForNamespaceScopeDecl
+  // marking them as internal.
+  if (Context.getLangOpts().CPlusPlus &&
+      Context.getLangOpts().IncrementalExtensions &&
+      VD->getType().isConstQualified() &&
+      !VD->getType().isVolatileQualified() && !VD->isInline() &&
+      !isa<VarTemplateSpecializationDecl>(VD) && !VD->getDescribedVarTemplate())
+    return GVA_DiscardableODR;
+
   if (!VD->isExternallyVisible())
     return GVA_Internal;
 

diff  --git a/clang/test/Interpreter/const.cpp b/clang/test/Interpreter/const.cpp
new file mode 100644
index 000000000000000..a4b610f1a19d842
--- /dev/null
+++ b/clang/test/Interpreter/const.cpp
@@ -0,0 +1,29 @@
+// UNSUPPORTED: system-aix
+// RUN: cat %s | clang-repl | FileCheck %s
+// RUN: cat %s | clang-repl -Xcc -O2 | FileCheck %s
+
+extern "C" int printf(const char*, ...);
+
+struct A { int val; A(int v); ~A(); void f() const; };
+A::A(int v) : val(v) { printf("A(%d), this = %p\n", val, this); }
+A::~A() { printf("~A, this = %p, val = %d\n", this, val); }
+void A::f() const { printf("f: this = %p, val = %d\n", this, val); }
+
+const A a(1);
+// CHECK: A(1), this = [[THIS:0x[0-9a-f]+]]
+// The constructor must only be called once!
+// CHECK-NOT: A(1)
+
+a.f();
+// CHECK-NEXT: f: this = [[THIS]], val = 1
+a.f();
+// CHECK-NEXT: f: this = [[THIS]], val = 1
+
+%quit
+// There must still be no other constructor!
+// CHECK-NOT: A(1)
+
+// At the end, we expect exactly one destructor call
+// CHECK: ~A
+// CHECK-SAME: this = [[THIS]], val = 1
+// CHECK-NOT: ~A


        


More information about the cfe-commits mailing list