@@ -128,6 +128,28 @@ static bool checkArgCountAtLeast(Sema &S, CallExpr *Call,
128
128
<< Call->getSourceRange();
129
129
}
130
130
131
+ /// Checks that a call expression's argument count is at most the desired
132
+ /// number. This is useful when doing custom type-checking on a variadic
133
+ /// function. Returns true on error.
134
+ static bool checkArgCountAtMost(Sema &S, CallExpr *Call, unsigned MaxArgCount) {
135
+ unsigned ArgCount = Call->getNumArgs();
136
+ if (ArgCount <= MaxArgCount)
137
+ return false;
138
+ return S.Diag(Call->getEndLoc(),
139
+ diag::err_typecheck_call_too_many_args_at_most)
140
+ << 0 /*function call*/ << MaxArgCount << ArgCount
141
+ << Call->getSourceRange();
142
+ }
143
+
144
+ /// Checks that a call expression's argument count is in the desired range. This
145
+ /// is useful when doing custom type-checking on a variadic function. Returns
146
+ /// true on error.
147
+ static bool checkArgCountRange(Sema &S, CallExpr *Call, unsigned MinArgCount,
148
+ unsigned MaxArgCount) {
149
+ return checkArgCountAtLeast(S, Call, MinArgCount) ||
150
+ checkArgCountAtMost(S, Call, MaxArgCount);
151
+ }
152
+
131
153
/// Checks that a call expression's argument count is the desired number.
132
154
/// This is useful when doing custom type-checking. Returns true on error.
133
155
static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) {
@@ -148,6 +170,20 @@ static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) {
148
170
<< Call->getArg(1)->getSourceRange();
149
171
}
150
172
173
+ static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty) {
174
+ if (Value->isTypeDependent())
175
+ return false;
176
+
177
+ InitializedEntity Entity =
178
+ InitializedEntity::InitializeParameter(S.Context, Ty, false);
179
+ ExprResult Result =
180
+ S.PerformCopyInitialization(Entity, SourceLocation(), Value);
181
+ if (Result.isInvalid())
182
+ return true;
183
+ Value = Result.get();
184
+ return false;
185
+ }
186
+
151
187
/// Check that the first argument to __builtin_annotation is an integer
152
188
/// and the second argument is a non-wide string literal.
153
189
static bool SemaBuiltinAnnotation(Sema &S, CallExpr *TheCall) {
@@ -7644,38 +7680,45 @@ bool Sema::SemaBuiltinAllocaWithAlign(CallExpr *TheCall) {
7644
7680
/// Handle __builtin_assume_aligned. This is declared
7645
7681
/// as (const void*, size_t, ...) and can take one optional constant int arg.
7646
7682
bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {
7683
+ if (checkArgCountRange(*this, TheCall, 2, 3))
7684
+ return true;
7685
+
7647
7686
unsigned NumArgs = TheCall->getNumArgs();
7687
+ Expr *FirstArg = TheCall->getArg(0);
7648
7688
7649
- if (NumArgs > 3)
7650
- return Diag(TheCall->getEndLoc(),
7651
- diag::err_typecheck_call_too_many_args_at_most)
7652
- << 0 /*function call*/ << 3 << NumArgs << TheCall->getSourceRange();
7689
+ {
7690
+ ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);
7691
+ if (FirstArgResult.isInvalid())
7692
+ return true;
7693
+ TheCall->setArg(0, FirstArgResult.get());
7694
+ }
7653
7695
7654
7696
// The alignment must be a constant integer.
7655
- Expr *Arg = TheCall->getArg(1);
7697
+ Expr *SecondArg = TheCall->getArg(1);
7698
+ if (convertArgumentToType(*this, SecondArg, Context.getSizeType()))
7699
+ return true;
7700
+ TheCall->setArg(1, SecondArg);
7656
7701
7657
7702
// We can't check the value of a dependent argument.
7658
- if (!Arg->isTypeDependent() && !Arg ->isValueDependent()) {
7703
+ if (!SecondArg ->isValueDependent()) {
7659
7704
llvm::APSInt Result;
7660
7705
if (SemaBuiltinConstantArg(TheCall, 1, Result))
7661
7706
return true;
7662
7707
7663
7708
if (!Result.isPowerOf2())
7664
7709
return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)
7665
- << Arg ->getSourceRange();
7710
+ << SecondArg ->getSourceRange();
7666
7711
7667
7712
if (Result > Sema::MaximumAlignment)
7668
7713
Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)
7669
- << Arg ->getSourceRange() << Sema::MaximumAlignment;
7714
+ << SecondArg ->getSourceRange() << Sema::MaximumAlignment;
7670
7715
}
7671
7716
7672
7717
if (NumArgs > 2) {
7673
- ExprResult Arg(TheCall->getArg(2));
7674
- InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
7675
- Context.getSizeType(), false);
7676
- Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);
7677
- if (Arg.isInvalid()) return true;
7678
- TheCall->setArg(2, Arg.get());
7718
+ Expr *ThirdArg = TheCall->getArg(2);
7719
+ if (convertArgumentToType(*this, ThirdArg, Context.getSizeType()))
7720
+ return true;
7721
+ TheCall->setArg(2, ThirdArg);
7679
7722
}
7680
7723
7681
7724
return false;
0 commit comments