https://github.com/Sirraide created https://github.com/llvm/llvm-project/pull/75883
It seems we were forgetting to call `checkArgsForPlaceholders` on the placement arguments of new-expressions in Sema. I don't think that was intended—at least doing so doesn't seem to break anything—so this pr adds that. This also fixes #65053 >From f51b382fd33d4cf3f75bdaa172bb8697a6cadc9e Mon Sep 17 00:00:00 2001 From: Sirraide <aeternalm...@gmail.com> Date: Tue, 19 Dec 2023 02:48:25 +0100 Subject: [PATCH] [Clang] Support MSPropertyRefExpr as placement arg to new-expression --- clang/include/clang/Sema/Sema.h | 4 ++ clang/lib/Sema/SemaExpr.cpp | 12 ++---- clang/lib/Sema/SemaExprCXX.cpp | 3 ++ clang/test/CodeGenCXX/ms-property-new.cpp | 52 +++++++++++++++++++++++ clang/test/SemaCXX/ms-property-new.cpp | 44 +++++++++++++++++++ 5 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGenCXX/ms-property-new.cpp create mode 100644 clang/test/SemaCXX/ms-property-new.cpp diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a4f8fc1845b1ce..90be0a648f0124 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2108,6 +2108,10 @@ class Sema final { bool CheckFunctionReturnType(QualType T, SourceLocation Loc); + /// Check an argument list for placeholders that we won't try to + /// handle later. + bool CheckArgsForPlaceholders(MultiExprArg args); + /// Build a function type. /// /// This routine checks the function type according to C++ rules and diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c7185d56cc9973..2442c1e104055b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5058,8 +5058,6 @@ static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS, return Result->isDependentType() ? Result : Ctx.DependentTy; } -static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args); - ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, MultiExprArg ArgExprs, @@ -5163,7 +5161,7 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, return ExprError(); ArgExprs[0] = result.get(); } else { - if (checkArgsForPlaceholders(*this, ArgExprs)) + if (CheckArgsForPlaceholders(ArgExprs)) return ExprError(); } @@ -6912,15 +6910,13 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { llvm_unreachable("bad builtin type kind"); } -/// Check an argument list for placeholders that we won't try to -/// handle later. -static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) { +bool Sema::CheckArgsForPlaceholders(MultiExprArg args) { // Apply this processing to all the arguments at once instead of // dying at the first failure. bool hasInvalid = false; for (size_t i = 0, e = args.size(); i != e; i++) { if (isPlaceholderToRemoveAsArg(args[i]->getType())) { - ExprResult result = S.CheckPlaceholderExpr(args[i]); + ExprResult result = CheckPlaceholderExpr(args[i]); if (result.isInvalid()) hasInvalid = true; else args[i] = result.get(); } @@ -7194,7 +7190,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if (Result.isInvalid()) return ExprError(); Fn = Result.get(); - if (checkArgsForPlaceholders(*this, ArgExprs)) + if (CheckArgsForPlaceholders(ArgExprs)) return ExprError(); if (getLangOpts().CPlusPlus) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 081b568762ae22..49f0921ce324fc 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2286,6 +2286,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, bool PassAlignment = getLangOpts().AlignedAllocation && Alignment > NewAlignment; + if (CheckArgsForPlaceholders(PlacementArgs)) + return ExprError(); + AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both; if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && diff --git a/clang/test/CodeGenCXX/ms-property-new.cpp b/clang/test/CodeGenCXX/ms-property-new.cpp new file mode 100644 index 00000000000000..e21ec3d6702f62 --- /dev/null +++ b/clang/test/CodeGenCXX/ms-property-new.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s +// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct S { + int GetX() { return 42; } + __declspec(property(get=GetX)) int x; + + int GetY(int i, int j) { return i+j; } + __declspec(property(get=GetY)) int y[]; + + void* operator new(__SIZE_TYPE__, int); +}; + +template <typename T> +struct TS { + T GetT() { return T(); } + __declspec(property(get=GetT)) T t; + + T GetR(T i, T j) { return i+j; } + __declspec(property(get=GetR)) T r[]; +}; + +// CHECK-LABEL: main +int main(int argc, char **argv) { + S *s; + TS<double> *ts; + + // CHECK: [[X:%.+]] = call noundef i32 @"?GetX@S@@QEAAHXZ"(ptr {{[^,]*}} %{{.+}}) + // CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[X]]) + new (s->x) S; + + // CHECK: [[Y:%.+]] = call noundef i32 @"?GetY@S@@QEAAHHH@Z"(ptr {{[^,]*}} %{{.+}}, i32 noundef 1, i32 noundef 2) + // CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[Y]]) + new ((s->y)[1][2]) S; + + // CHECK: [[T:%.+]] = call noundef double @"?GetT@?$TS@N@@QEAANXZ"(ptr {{[^,]*}} %{{.+}}) + // CHECK-NEXT: [[TI:%.+]] = fptosi double [[T]] to i32 + // CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[TI]]) + new (ts->t) S; + + // CHECK: [[R:%.+]] = call noundef double @"?GetR@?$TS@N@@QEAANNN@Z"(ptr {{[^,]*}} %{{.+}}, double {{[^,]*}}, double {{[^,]*}}) + // CHECK-NEXT: [[RI:%.+]] = fptosi double [[R]] to i32 + // CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[RI]]) + new ((ts->r)[1][2]) S; +} + +#endif \ No newline at end of file diff --git a/clang/test/SemaCXX/ms-property-new.cpp b/clang/test/SemaCXX/ms-property-new.cpp new file mode 100644 index 00000000000000..d17b0fdeb76715 --- /dev/null +++ b/clang/test/SemaCXX/ms-property-new.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -ast-print -verify -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -ast-print -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct S { + int GetX() { return 42; } + __declspec(property(get=GetX)) int x; + + int GetY(int i, int j) { return i+j; } + __declspec(property(get=GetY)) int y[]; + + void* operator new(__SIZE_TYPE__, int); +}; + +template <typename T> +struct TS { + T GetT() { return T(); } + __declspec(property(get=GetT)) T t; + + T GetR(T i, T j) { return i+j; } + __declspec(property(get=GetR)) T r[]; +}; + +int main(int argc, char **argv) { + // CHECK: S *s; + // CHECK-NEXT: new (s->x) S; + // CHECK-NEXT: new ((s->y)[1][2]) S; + S *s; + new (s->x) S; + new ((s->y)[1][2]) S; + + // CHECK-NEXT: TS<double> *ts; + // CHECK-NEXT: new (ts->t) S; + // CHECK-NEXT: new ((ts->r)[1][2]) S; + TS<double> *ts; + new (ts->t) S; + new ((ts->r)[1][2]) S; +} + +#endif \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits