Skip to content

Commit 76a3200

Browse files
committed
Call rule printf when format string is not static
1 parent 2bb3063 commit 76a3200

6 files changed

Lines changed: 40 additions & 12 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,8 +2311,13 @@ std::optional<Converter::TempMaterializationCtx>
23112311
Converter::ConvertCallExpr(clang::CallExpr *expr) {
23122312
auto *callee = expr->getCallee();
23132313

2314-
if (auto fn = Printer::ToString(ctx_, callee);
2315-
fn.starts_with("int printf") || fn.starts_with("int fprintf")) {
2314+
auto fn = Printer::ToString(ctx_, callee);
2315+
bool is_printf = fn.starts_with("int printf");
2316+
bool is_fprintf = fn.starts_with("int fprintf");
2317+
unsigned format_arg = is_fprintf ? 1 : 0;
2318+
if ((is_printf || is_fprintf) &&
2319+
clang::isa<clang::StringLiteral>(
2320+
expr->getArg(format_arg)->IgnoreImplicit())) {
23162321
ConvertPrintf(expr);
23172322
} else if (IsTransparentStdCall(expr)) {
23182323
Convert(expr->getArg(0));

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,16 +1244,8 @@ static std::vector<const char *> printf2fmt(std::string &format) {
12441244
void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
12451245
bool is_fprintf =
12461246
Printer::ToString(ctx_, expr->getCallee()).starts_with("int fprintf");
1247-
std::string format;
1248-
if (auto *str = clang::dyn_cast<clang::StringLiteral>(
1249-
expr->getArg(is_fprintf)->IgnoreImplicit())) {
1250-
format = GetEscapedStringLiteral(str);
1251-
} else {
1252-
llvm::errs() << "Unknown fprintf format: ";
1253-
expr->getArg(1)->dump();
1254-
llvm::errs() << '\n';
1255-
exit(1);
1256-
}
1247+
auto format = GetEscapedStringLiteral(clang::cast<clang::StringLiteral>(
1248+
expr->getArg(is_fprintf)->IgnoreImplicit()));
12571249
bool ends_newline = format.ends_with("\\n\"");
12581250

12591251
auto fd = is_fprintf ? Printer::ToString(ctx_, expr->getArg(0)) : "stdout";

‎rules/stdio/src.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ int f25(void) { return SEEK_SET; }
7575
int f26(void) { return SEEK_CUR; }
7676

7777
int f27(void) { return SEEK_END; }
78+
79+
int (*f28)(FILE *, const char *, ...) = fprintf;
80+
81+
int (*f29)(const char *, ...) = printf;

‎rules/stdio/tgt_refcount.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,13 @@ fn f23(a0: Ptr<CFile>) -> i32 {
189189
fn f24(a0: Ptr<CFile>, a1: Ptr<i8>, a2: i32, a3: usize) -> i32 {
190190
0
191191
}
192+
193+
fn f28(a0: Ptr<CFile>, a1: Ptr<i8>, va: &[VaArg]) -> i32 {
194+
let __s = libcc2rs::format_c(&a1.to_rust_string(), va);
195+
a0.with_mut(|__f| __f.write(__s.as_bytes())) as i32
196+
}
197+
198+
fn f29(a0: Ptr<i8>, va: &[VaArg]) -> i32 {
199+
let __s = libcc2rs::format_c(&a0.to_rust_string(), va);
200+
libcc2rs::c_stdout().with_mut(|__f| __f.write(__s.as_bytes())) as i32
201+
}

‎rules/stdio/tgt_unsafe.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,11 @@ unsafe fn f26() -> i32 {
116116
unsafe fn f27() -> i32 {
117117
::libc::SEEK_END
118118
}
119+
120+
unsafe extern "C" {
121+
fn f28(a0: *mut ::libc::FILE, a1: *const libc::c_char, ...) -> i32;
122+
}
123+
124+
unsafe extern "C" {
125+
fn f29(a0: *const libc::c_char, ...) -> i32;
126+
}

‎tests/unit/printfs.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ std::string fn(std::string v) { return v + " str"; }
66

77
const std::string &fn2(const std::string &v) { return v; }
88

9+
template <class... Args> void log_to(FILE *out, const char *fmt, Args... args) {
10+
fprintf(out, fmt, args...);
11+
}
12+
13+
void log_fmt(const char *fmt, int v) { printf(fmt, v); }
14+
915
int main() {
1016
fprintf(stdout, "%s\n", "fprintf stdout");
1117
fprintf(stdout, "%d %u %ld\n", 1, 2U, 3L);
@@ -18,5 +24,8 @@ int main() {
1824
printf("%s\n", s.data());
1925
printf("%s\n", fn("foo").c_str());
2026
printf("%s\n", fn2(s).c_str());
27+
log_to(stdout, "%s %d\n", "runtime", 4);
28+
log_to(stderr, "%d\n", 5);
29+
log_fmt("%d\n", 6);
2130
return 0;
2231
}

0 commit comments

Comments
 (0)