Skip to content

Conversation

@andykaylor
Copy link
Contributor

This adds handling emitting C++ default arguments as l-values.

This adds handling emitting C++ default arguments as l-values.
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Nov 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2025

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

This adds handling emitting C++ default arguments as l-values.


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

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5)
  • (added) clang/test/CIR/CodeGen/defaultarg.cpp (+32)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index f1be14222434f..866fda3166f41 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -928,6 +928,11 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
     assert(!cir::MissingFeatures::cleanupWithPreservedValues());
     return lv;
   }
+  case Expr::CXXDefaultArgExprClass: {
+    auto *dae = cast<CXXDefaultArgExpr>(e);
+    CXXDefaultArgExprScope scope(*this, dae);
+    return emitLValue(dae->getExpr());
+  }
   case Expr::ParenExprClass:
     return emitLValue(cast<ParenExpr>(e)->getSubExpr());
   case Expr::GenericSelectionExprClass:
diff --git a/clang/test/CIR/CodeGen/defaultarg.cpp b/clang/test/CIR/CodeGen/defaultarg.cpp
new file mode 100644
index 0000000000000..807230bd003f5
--- /dev/null
+++ b/clang/test/CIR/CodeGen/defaultarg.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -std=c++17 %s -o %t.cir
+// RUN: FileCheck %s --input-file=%t.cir --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -std=c++17 %s -o %t-cir.ll
+// RUN: FileCheck %s --input-file=%t-cir.ll --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++17 %s -o %t.ll
+// RUN: FileCheck %s --input-file=%t.ll --check-prefix=OGCG
+
+void bar(const int &i = 42);
+
+void foo() {
+  bar();
+}
+
+// CIR: cir.func {{.*}} @_Z3foov()
+// CIR:   cir.scope {
+// CIR:     %[[TMP0:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp0"]
+// CIR:     %[[TMP1:.*]] = cir.const #cir.int<42>
+// CIR:     cir.store{{.*}} %[[TMP1]], %[[TMP0]]
+// CIR:     cir.call @_Z3barRKi(%[[TMP0]])
+// CIR:   }
+
+// LLVM: define{{.*}} @_Z3foov()
+// LLVM:   %[[TMP0:.*]] = alloca i32
+// LLVM:   br label %[[SCOPE_LABEL:.*]]
+// LLVM: [[SCOPE_LABEL]]:
+// LLVM:   store i32 42, ptr %[[TMP0]]
+// LLVM:   call void @_Z3barRKi(ptr %[[TMP0]])
+
+// OGCG: define{{.*}} @_Z3foov()
+// OGCG:   %[[TMP0:.*]] = alloca i32
+// OGCG:   store i32 42, ptr %[[TMP0]]
+// OGCG:   call void @_Z3barRKi(ptr {{.*}} %[[TMP0]])

@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2025

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

Changes

This adds handling emitting C++ default arguments as l-values.


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

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5)
  • (added) clang/test/CIR/CodeGen/defaultarg.cpp (+32)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index f1be14222434f..866fda3166f41 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -928,6 +928,11 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
     assert(!cir::MissingFeatures::cleanupWithPreservedValues());
     return lv;
   }
+  case Expr::CXXDefaultArgExprClass: {
+    auto *dae = cast<CXXDefaultArgExpr>(e);
+    CXXDefaultArgExprScope scope(*this, dae);
+    return emitLValue(dae->getExpr());
+  }
   case Expr::ParenExprClass:
     return emitLValue(cast<ParenExpr>(e)->getSubExpr());
   case Expr::GenericSelectionExprClass:
diff --git a/clang/test/CIR/CodeGen/defaultarg.cpp b/clang/test/CIR/CodeGen/defaultarg.cpp
new file mode 100644
index 0000000000000..807230bd003f5
--- /dev/null
+++ b/clang/test/CIR/CodeGen/defaultarg.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -std=c++17 %s -o %t.cir
+// RUN: FileCheck %s --input-file=%t.cir --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -std=c++17 %s -o %t-cir.ll
+// RUN: FileCheck %s --input-file=%t-cir.ll --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++17 %s -o %t.ll
+// RUN: FileCheck %s --input-file=%t.ll --check-prefix=OGCG
+
+void bar(const int &i = 42);
+
+void foo() {
+  bar();
+}
+
+// CIR: cir.func {{.*}} @_Z3foov()
+// CIR:   cir.scope {
+// CIR:     %[[TMP0:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp0"]
+// CIR:     %[[TMP1:.*]] = cir.const #cir.int<42>
+// CIR:     cir.store{{.*}} %[[TMP1]], %[[TMP0]]
+// CIR:     cir.call @_Z3barRKi(%[[TMP0]])
+// CIR:   }
+
+// LLVM: define{{.*}} @_Z3foov()
+// LLVM:   %[[TMP0:.*]] = alloca i32
+// LLVM:   br label %[[SCOPE_LABEL:.*]]
+// LLVM: [[SCOPE_LABEL]]:
+// LLVM:   store i32 42, ptr %[[TMP0]]
+// LLVM:   call void @_Z3barRKi(ptr %[[TMP0]])
+
+// OGCG: define{{.*}} @_Z3foov()
+// OGCG:   %[[TMP0:.*]] = alloca i32
+// OGCG:   store i32 42, ptr %[[TMP0]]
+// OGCG:   call void @_Z3barRKi(ptr {{.*}} %[[TMP0]])

@andykaylor andykaylor merged commit 518b38c into llvm:main Nov 14, 2025
13 checks passed
@andykaylor andykaylor deleted the cir-defaultarg branch November 14, 2025 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants