Skip to content

Commit 849b21f

Browse files
committed
[Clang] Support MSPropertyRefExpr as placement arg to new-expression
1 parent 5fcf907 commit 849b21f

File tree

5 files changed

+107
-8
lines changed

5 files changed

+107
-8
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,10 @@ class Sema final {
21082108

21092109
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
21102110

2111+
/// Check an argument list for placeholders that we won't try to
2112+
/// handle later.
2113+
bool CheckArgsForPlaceholders(MultiExprArg args);
2114+
21112115
/// Build a function type.
21122116
///
21132117
/// This routine checks the function type according to C++ rules and

clang/lib/Sema/SemaExpr.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,8 +5058,6 @@ static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
50585058
return Result->isDependentType() ? Result : Ctx.DependentTy;
50595059
}
50605060

5061-
static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args);
5062-
50635061
ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
50645062
SourceLocation lbLoc,
50655063
MultiExprArg ArgExprs,
@@ -5163,7 +5161,7 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
51635161
return ExprError();
51645162
ArgExprs[0] = result.get();
51655163
} else {
5166-
if (checkArgsForPlaceholders(*this, ArgExprs))
5164+
if (CheckArgsForPlaceholders(ArgExprs))
51675165
return ExprError();
51685166
}
51695167

@@ -6912,15 +6910,13 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
69126910
llvm_unreachable("bad builtin type kind");
69136911
}
69146912

6915-
/// Check an argument list for placeholders that we won't try to
6916-
/// handle later.
6917-
static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) {
6913+
bool Sema::CheckArgsForPlaceholders(MultiExprArg args) {
69186914
// Apply this processing to all the arguments at once instead of
69196915
// dying at the first failure.
69206916
bool hasInvalid = false;
69216917
for (size_t i = 0, e = args.size(); i != e; i++) {
69226918
if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
6923-
ExprResult result = S.CheckPlaceholderExpr(args[i]);
6919+
ExprResult result = CheckPlaceholderExpr(args[i]);
69246920
if (result.isInvalid()) hasInvalid = true;
69256921
else args[i] = result.get();
69266922
}
@@ -7194,7 +7190,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
71947190
if (Result.isInvalid()) return ExprError();
71957191
Fn = Result.get();
71967192

7197-
if (checkArgsForPlaceholders(*this, ArgExprs))
7193+
if (CheckArgsForPlaceholders(ArgExprs))
71987194
return ExprError();
71997195

72007196
if (getLangOpts().CPlusPlus) {

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,6 +2286,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
22862286
bool PassAlignment = getLangOpts().AlignedAllocation &&
22872287
Alignment > NewAlignment;
22882288

2289+
if (CheckArgsForPlaceholders(PlacementArgs))
2290+
return ExprError();
2291+
22892292
AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
22902293
if (!AllocType->isDependentType() &&
22912294
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
3+
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -o - | FileCheck %s
4+
// expected-no-diagnostics
5+
6+
#ifndef HEADER
7+
#define HEADER
8+
9+
struct S {
10+
int GetX() { return 42; }
11+
__declspec(property(get=GetX)) int x;
12+
13+
int GetY(int i, int j) { return i+j; }
14+
__declspec(property(get=GetY)) int y[];
15+
16+
void* operator new(__SIZE_TYPE__, int);
17+
};
18+
19+
template <typename T>
20+
struct TS {
21+
T GetT() { return T(); }
22+
__declspec(property(get=GetT)) T t;
23+
24+
T GetR(T i, T j) { return i+j; }
25+
__declspec(property(get=GetR)) T r[];
26+
};
27+
28+
// CHECK-LABEL: main
29+
int main(int argc, char **argv) {
30+
S *s;
31+
TS<double> *ts;
32+
33+
// CHECK: [[X:%.+]] = call noundef i32 @"?GetX@S@@QEAAHXZ"(ptr {{[^,]*}} %{{.+}})
34+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[X]])
35+
new (s->x) S;
36+
37+
// CHECK: [[Y:%.+]] = call noundef i32 @"?GetY@S@@QEAAHHH@Z"(ptr {{[^,]*}} %{{.+}}, i32 noundef 1, i32 noundef 2)
38+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[Y]])
39+
new ((s->y)[1][2]) S;
40+
41+
// CHECK: [[T:%.+]] = call noundef double @"?GetT@?$TS@N@@QEAANXZ"(ptr {{[^,]*}} %{{.+}})
42+
// CHECK-NEXT: [[TI:%.+]] = fptosi double [[T]] to i32
43+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[TI]])
44+
new (ts->t) S;
45+
46+
// CHECK: [[R:%.+]] = call noundef double @"?GetR@?$TS@N@@QEAANNN@Z"(ptr {{[^,]*}} %{{.+}}, double {{[^,]*}}, double {{[^,]*}})
47+
// CHECK-NEXT: [[RI:%.+]] = fptosi double [[R]] to i32
48+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[RI]])
49+
new ((ts->r)[1][2]) S;
50+
}
51+
52+
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 -ast-print -verify -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
3+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -ast-print -o - | FileCheck %s
4+
// expected-no-diagnostics
5+
6+
#ifndef HEADER
7+
#define HEADER
8+
9+
struct S {
10+
int GetX() { return 42; }
11+
__declspec(property(get=GetX)) int x;
12+
13+
int GetY(int i, int j) { return i+j; }
14+
__declspec(property(get=GetY)) int y[];
15+
16+
void* operator new(__SIZE_TYPE__, int);
17+
};
18+
19+
template <typename T>
20+
struct TS {
21+
T GetT() { return T(); }
22+
__declspec(property(get=GetT)) T t;
23+
24+
T GetR(T i, T j) { return i+j; }
25+
__declspec(property(get=GetR)) T r[];
26+
};
27+
28+
int main(int argc, char **argv) {
29+
// CHECK: S *s;
30+
// CHECK-NEXT: new (s->x) S;
31+
// CHECK-NEXT: new ((s->y)[1][2]) S;
32+
S *s;
33+
new (s->x) S;
34+
new ((s->y)[1][2]) S;
35+
36+
// CHECK-NEXT: TS<double> *ts;
37+
// CHECK-NEXT: new (ts->t) S;
38+
// CHECK-NEXT: new ((ts->r)[1][2]) S;
39+
TS<double> *ts;
40+
new (ts->t) S;
41+
new ((ts->r)[1][2]) S;
42+
}
43+
44+
#endif

0 commit comments

Comments
 (0)