On Fri, Feb 10, 2012 at 12:43 PM, David Blaikie <[email protected]> wrote:
> On Fri, Feb 10, 2012 at 11:52 AM, Ted Kremenek <[email protected]> wrote:
>> On Feb 10, 2012, at 11:42 AM, David Blaikie <[email protected]> wrote:
>>
>> On Fri, Feb 10, 2012 at 11:13 AM, Ted Kremenek <[email protected]> wrote:
>>
>> Author: kremenek
>> Date: Fri Feb 10 13:13:51 2012
>> New Revision: 150260
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=150260&view=rev
>> Log:
>> Enhance checking for null format string literal to take into account __null.
>> Fixes <rdar://problem/8269537>.
>>
>> Modified:
>> cfe/trunk/lib/Sema/SemaChecking.cpp
>> cfe/trunk/test/SemaCXX/format-strings.cpp
>>
>> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=150260&r1=150259&r2=150260&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb 10 13:13:51 2012
>> @@ -1381,6 +1381,7 @@
>> inFunctionCall);
>> }
>>
>> + case Stmt::GNUNullExprClass:
>> case Stmt::IntegerLiteralClass:
>>
>>
>> could/should this be generalized over all null pointer literals?
>>
>>
>> Absolutely.
>>
>>
>> This, for example, still flags 'nullptr' and (to a more questionable
>> extent) 'false' which is still technically a valid null pointer. If
>> I'm reading/testing it correctly, that is.
>>
>>
>> It's questionable whether we should be happy with any integer literal, but
>> definitely we should not warn about any cases of null.
>
> The trick is any integer literal that didn't fail to compile in this
> context is a null pointer. Anyway, here's a patch that generalizes
> nicely along with some extra test cases it implements.
>
> - David
[oops, missed a warning suppression/validation for 'false' as a null
pointer literal - I used an expected-warning, but I'm actually
undecided about whether we should do that in general (ad expected
warnings for warnings we aren't trying to test) rather than just
disable that warning in this test case (or, indeed, disable all
warnings except the ones we plan to test in a given test case - though
that might lose us a lot of fairly useful (if scattershot) accidental
coverage)]
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index be32688..cf04695 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1369,6 +1369,13 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, Expr **Args,
E = E->IgnoreParenCasts();
+ if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+ // Technically -Wformat-nonliteral does not warn about this case.
+ // The behavior of printf and friends in this case is implementation
+ // dependent. Ideally if the format string cannot be null then
+ // it should have a 'nonnull' attribute in the function prototype.
+ return true;
+
switch (E->getStmtClass()) {
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: {
@@ -1381,14 +1388,6 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, Expr **Args,
inFunctionCall);
}
- case Stmt::GNUNullExprClass:
- case Stmt::IntegerLiteralClass:
- // Technically -Wformat-nonliteral does not warn about this case.
- // The behavior of printf and friends in this case is implementation
- // dependent. Ideally if the format string cannot be null then
- // it should have a 'nonnull' attribute in the function prototype.
- return true;
-
case Stmt::ImplicitCastExprClass: {
E = cast<ImplicitCastExpr>(E)->getSubExpr();
goto tryAgain;
diff --git a/test/SemaCXX/format-strings-0x.cpp b/test/SemaCXX/format-strings-0x.cpp
index 9359c7b..5f3f684 100644
--- a/test/SemaCXX/format-strings-0x.cpp
+++ b/test/SemaCXX/format-strings-0x.cpp
@@ -10,4 +10,5 @@ void f(char **sp, float *fp) {
printf("%a", 1.0);
scanf("%afoobar", fp);
+ printf(nullptr);
}
diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp
index 456167d..0d5b625 100644
--- a/test/SemaCXX/format-strings.cpp
+++ b/test/SemaCXX/format-strings.cpp
@@ -47,6 +47,8 @@ extern "C" {
void rdar8269537(const char *f)
{
+ test_null_format(false); // expected-warning {{null from a constant boolean}}
+ test_null_format(0); // no-warning
test_null_format(__null); // no-warning
test_null_format(f); // expected-warning {{not a string literal}}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits