[cfe-commits] Warning for bad std::string constructor invocations
Manuel Klimek
klimek at google.com
Wed Dec 7 06:30:49 PST 2011
A few nits.
+ const StringLiteral *ExprAsStringLiteral =+
dyn_cast<StringLiteral>(Expression);
Here and elsewhere: 2-space indent
+ // Expr might be referencing a string literal.
+ const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Expression);
double-space before '='
+ if (const ArrayType *AT = s.Context.getAsArrayType(T)) {
+ IsConstant = AT->getElementType().isConstant(s.Context);
+ } else if (const PointerType *PT = T->getAs<PointerType>()) {
+ IsConstant = T.isConstant(s.Context) &&
+ PT->getPointeeType().isConstant(s.Context);
Why is T.isConstant(...) needed here? Could you answer that in a
comment? (I think it's non-obvious)
+ S.Diag(Arg0->getExprLoc(),
+ diag::warn_std_string_ctor_out_of_bounds)
+ << LiteralLength << SecondArgValue.toString(10)
+ << Arg0->getSourceRange() << Arg1->getSourceRange();
Strange indent...
+static void checkBasicStringConstructorCharToIntCast(
+ Sema &S, SourceLocation ConstructLoc, CXXConstructorDecl *Constructor,
+ MultiExprArg ExprArgs) {
+ const QualType ParamType0 = Constructor->getParamDecl(0)->getType();
+ const QualType ParamType1 = Constructor->getParamDecl(1)->getType();
+ if (!ParamType0->isIntegerType()) return;
+ if (!ParamType1->isAnyCharacterType()) return;
+ // This is a call to the constructor [cf. C++11 [string.cons] 21.4.2/9 ]:
+ // basic_string(size_type n, char c, const _Alloc& a = _Alloc());
+ // If the constructor is called with a char literal as n and an integer as
+ // c, this is almost certainly unintended.
I don't see where the second condition "integer as c" is checked... If
that's not a condition, I wouldn't mention it.
Cheers,
/Manuel
On Mon, Dec 5, 2011 at 6:08 PM, Ingo Walther <ingow at google.com> wrote:
> This patch introduces two new warnings about bad std::string constructor
> invocation. They can be turned on with -Wstring-constructor.
>
> The first pattern it catches is:
> std::string s('a', 10);
>
> The intention probably was to call
> std::string s(10, 'a');
>
> which creates "aaaaaaaaaa". But implicit casts actually turn it into
> std::string s(97, '\10');
>
> The new warning says:
>
> str.cc:6:17: warning: argument implicitly cast from 'char' to 'size_type'
> (aka 'unsigned long') [-Wstring-constructor]
> std::string s('a', 10);
> ^~~
> str.cc:6:17: note: did you mean to swap the two arguments?
> std::string s('a', 10);
> ^~~~~~~
> 10, 'a'
>
>
> The second pattern the patch catches is:
> std::string v("abc", 10);
>
> The constructor will read 10 characters into the new string, but there are
> only four (including the null terminator). This reads junk if we're lucky,
> and segfaults or opens security holes if we're unlucky.
>
> The new warning says:
> str.cc:9:17: warning: string literal is shorter than the number of
> characters to read (3 vs 10) [-Wstring-constructor]
> std::string v("abc", 10);
> ^~~~~ ~~
>
> If the literal is just one character long, we suggest to swap the arguments
> and turn the string literal into a char literal:
> str.cc:8:17: warning: string literal is shorter than the number of
> characters to read (1 vs 10) [-Wstring-constructor]
> std::string u("a", 10);
> ^~~ ~~
> str.cc:8:17: note: did you mean to swap the two arguments?
> std::string u("a", 10);
> ^~~~~~~
> 10, 'a'
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list