Skip to content

Commit d1c1e43

Browse files
committed
Don't use uninstantiated default argument
1 parent 70a4749 commit d1c1e43

6 files changed

Lines changed: 23 additions & 20 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
551551

552552
bool is_parm_with_default_value = false;
553553
if (auto parm = clang::dyn_cast<clang::ParmVarDecl>(decl)) {
554-
is_parm_with_default_value = parm->hasDefaultArg();
554+
is_parm_with_default_value = HasUsableDefaultArg(parm);
555555
}
556556

557557
if (is_parm_with_default_value) {
@@ -1226,7 +1226,7 @@ void Converter::EmitFunctionPreamble(clang::FunctionDecl *decl) {
12261226
auto params = decl->getDefinition() ? decl->getDefinition()->parameters()
12271227
: decl->parameters();
12281228
for (auto *param : params) {
1229-
if (param->hasDefaultArg()) {
1229+
if (HasUsableDefaultArg(param)) {
12301230
auto name = GetNamedDeclAsString(param);
12311231
auto type = ToString(param->getType());
12321232
auto init = std::format("{}.unwrap_or({})", name,
@@ -1943,7 +1943,8 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) {
19431943
.param_type = function ? function->getParamDecl(i)->getType()
19441944
: proto->getParamType(i),
19451945
.expr = arg,
1946-
.has_default = function && function->getParamDecl(i)->hasDefaultArg(),
1946+
.has_default =
1947+
function && HasUsableDefaultArg(function->getParamDecl(i)),
19471948
.kind = (IsLiteral(arg) || info.is_libc_passthrough) ? Kind::Inline
19481949
: Kind::Hoisted,
19491950
};
@@ -3573,7 +3574,7 @@ void Converter::ConvertCXXConstructExprArgs(clang::CXXConstructExpr *expr) {
35733574
for (unsigned param_idx = 0; param_idx < ctor->getNumParams(); ++param_idx) {
35743575
auto param = ctor->getParamDecl(param_idx);
35753576
auto param_type = param->getType();
3576-
bool has_default = param->hasDefaultArg();
3577+
bool has_default = HasUsableDefaultArg(param);
35773578

35783579
if (arg_idx < expr->getNumArgs() &&
35793580
clang::isa<clang::CXXDefaultArgExpr>(expr->getArg(arg_idx))) {

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ GetUserDefinedDefaultConstructor(const clang::CXXRecordDecl *decl) {
534534
return nullptr;
535535
}
536536

537+
bool HasUsableDefaultArg(const clang::ParmVarDecl *param) {
538+
return param->hasDefaultArg() && !param->hasUninstantiatedDefaultArg();
539+
}
540+
537541
std::string GetMainFileName(const clang::ASTContext &ctx) {
538542
const auto &src_mgr = ctx.getSourceManager();
539543
auto file_id = src_mgr.getMainFileID();

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ unsigned GetCtorIndex(clang::CXXConstructorDecl *ctor);
130130
clang::CXXConstructorDecl *
131131
GetUserDefinedDefaultConstructor(const clang::CXXRecordDecl *decl);
132132

133+
bool HasUsableDefaultArg(const clang::ParmVarDecl *param);
134+
133135
std::string GetMainFileName(const clang::ASTContext &ctx);
134136

135137
std::string GetFileName(const clang::Decl *decl);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ void ConverterRefCount::EmitFunctionPreamble(clang::FunctionDecl *decl) {
671671
auto type = ToString(param->getType());
672672
auto init = name;
673673

674-
if (param->hasDefaultArg()) {
674+
if (HasUsableDefaultArg(param)) {
675675
init = std::format("{}.unwrap_or({})", name,
676676
ToString(param->getDefaultArg()));
677677
}

‎tests/unit/out/refcount/template_default_arg.rs‎

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ pub fn scaled_2(x: A, n: Option<i32>) -> i32 {
143143
let n: Value<i32> = Rc::new(RefCell::new(n.unwrap_or((4usize as i32))));
144144
return ((*(*x.borrow()).v.borrow()) * (*n.borrow()));
145145
}
146-
pub fn always_given_3(x: Option<NoDefault>) -> i32 {
147-
let x: Value<NoDefault> = Rc::new(RefCell::new(x.unwrap_or()));
146+
pub fn always_given_3(x: NoDefault) -> i32 {
147+
let x: Value<NoDefault> = Rc::new(RefCell::new(x));
148148
return (*(*x.borrow()).v.borrow());
149149
}
150150
#[derive(Default)]
@@ -193,19 +193,17 @@ fn main_0() -> i32 {
193193
assert!((({ used_1(None,) }) == 2));
194194
assert!((({ scaled_2(A::A2({ 3 },), None,) }) == (3 * (4usize as i32))));
195195
assert!((({ scaled_2(A::A2({ 3 },), Some(2),) }) == 6));
196-
assert!((({ always_given_3(Some(NoDefault::NoDefault({ 3 },)),) }) == 3));
196+
assert!((({ always_given_3(NoDefault::NoDefault({ 3 },),) }) == 3));
197197
let s: Value<S_NoDefault_> = Rc::new(RefCell::new(S_NoDefault_::S_NoDefault_({ 1 })));
198-
assert!(
199-
(({ S_NoDefault_Impl::get(&s.as_pointer(), Some(NoDefault::NoDefault({ 4 },)),) }) == 5)
200-
);
198+
assert!((({ S_NoDefault_Impl::get(&s.as_pointer(), NoDefault::NoDefault({ 4 },),) }) == 5));
201199
return 0;
202200
}
203201
pub trait S_NoDefault_Impl {
204-
fn get(&self, t: Option<NoDefault>) -> i32;
202+
fn get(&self, t: NoDefault) -> i32;
205203
}
206204
impl S_NoDefault_Impl for Ptr<S_NoDefault_> {
207-
fn get(&self, t: Option<NoDefault>) -> i32 {
208-
let t: Value<NoDefault> = Rc::new(RefCell::new(t.unwrap_or()));
205+
fn get(&self, t: NoDefault) -> i32 {
206+
let t: Value<NoDefault> = Rc::new(RefCell::new(t));
209207
return ((*(*(*self).upgrade().deref()).v.borrow()) + (*(*t.borrow()).v.borrow()));
210208
}
211209
}

‎tests/unit/out/unsafe/template_default_arg.rs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ pub unsafe fn scaled_2(mut x: A, mut n: Option<i32>) -> i32 {
6565
let mut n: i32 = n.unwrap_or((::std::mem::size_of::<A>() as i32));
6666
return ((x.v) * (n));
6767
}
68-
pub unsafe fn always_given_3(mut x: Option<NoDefault>) -> i32 {
69-
let mut x: NoDefault = x.unwrap_or();
68+
pub unsafe fn always_given_3(mut x: NoDefault) -> i32 {
7069
return x.v;
7170
}
7271
#[repr(C)]
@@ -79,8 +78,7 @@ impl S_NoDefault_ {
7978
let mut this = Self { v: v };
8079
this
8180
}
82-
pub unsafe fn get(&self, mut t: Option<NoDefault>) -> i32 {
83-
let mut t: NoDefault = t.unwrap_or();
81+
pub unsafe fn get(&self, mut t: NoDefault) -> i32 {
8482
return ((self.v) + (t.v));
8583
}
8684
}
@@ -99,9 +97,9 @@ unsafe fn main_0() -> i32 {
9997
== ((3) * (::std::mem::size_of::<A>() as i32)))
10098
);
10199
assert!(((unsafe { scaled_2(A::A2({ 3 },), Some(2),) }) == (6)));
102-
assert!(((unsafe { always_given_3(Some(NoDefault::NoDefault({ 3 },)),) }) == (3)));
100+
assert!(((unsafe { always_given_3(NoDefault::NoDefault({ 3 },),) }) == (3)));
103101
let mut s: S_NoDefault_ = S_NoDefault_::S_NoDefault_({ 1 });
104-
assert!(((unsafe { S_NoDefault_::get(&s, Some(NoDefault::NoDefault({ 4 },)),) }) == (5)));
102+
assert!(((unsafe { S_NoDefault_::get(&s, NoDefault::NoDefault({ 4 },),) }) == (5)));
105103
return 0;
106104
}
107105
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)