зеркало из https://github.com/microsoft/clang-1.git
Change wording of 'memcpy' type mismatch warning and remove fixit.
As per comments following r157659. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157722 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
eaa069075f
Коммит
90c78328e7
|
@ -335,10 +335,14 @@ def warn_dyn_class_memaccess : Warning<
|
||||||
def note_bad_memaccess_silence : Note<
|
def note_bad_memaccess_silence : Note<
|
||||||
"explicitly cast the pointer to silence this warning">;
|
"explicitly cast the pointer to silence this warning">;
|
||||||
def warn_sizeof_pointer_expr_memaccess : Warning<
|
def warn_sizeof_pointer_expr_memaccess : Warning<
|
||||||
"argument to 'sizeof' in '%0' call is the same expression as the "
|
"'%0' call operates on objects of type %1 while the size is based on a "
|
||||||
"%select{destination|source}1; did you mean to "
|
"different type %2">,
|
||||||
"%select{dereference it|remove the addressof|provide an explicit length}2?">,
|
|
||||||
InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
|
InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
|
||||||
|
def warn_sizeof_pointer_expr_memaccess_note : Note<
|
||||||
|
"did you mean to %select{dereference the argument to 'sizeof' (and multiply "
|
||||||
|
"it by the number of elements)|remove the addressof in the argument to "
|
||||||
|
"'sizeof' (and multiply it by the number of elements)|provide an explicit "
|
||||||
|
"length}0?">;
|
||||||
def warn_sizeof_pointer_type_memaccess : Warning<
|
def warn_sizeof_pointer_type_memaccess : Warning<
|
||||||
"argument to 'sizeof' in %0 call is the same pointer type %1 as the "
|
"argument to 'sizeof' in %0 call is the same pointer type %1 as the "
|
||||||
"%select{destination|source}2; expected %3 or an explicit length">,
|
"%select{destination|source}2; expected %3 or an explicit length">,
|
||||||
|
|
|
@ -2755,24 +2755,14 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
|
||||||
// TODO: For strncpy() and friends, this could suggest sizeof(dst)
|
// TODO: For strncpy() and friends, this could suggest sizeof(dst)
|
||||||
// over sizeof(src) as well.
|
// over sizeof(src) as well.
|
||||||
unsigned ActionIdx = 0; // Default is to suggest dereferencing.
|
unsigned ActionIdx = 0; // Default is to suggest dereferencing.
|
||||||
FixItHint Fixit = FixItHint(); // Default hint.
|
|
||||||
StringRef ReadableName = FnName->getName();
|
StringRef ReadableName = FnName->getName();
|
||||||
|
|
||||||
if (isa<DeclRefExpr>(SizeOfArg))
|
|
||||||
Fixit = FixItHint::CreateInsertion(SizeOfArg->getLocStart(), "*");
|
|
||||||
|
|
||||||
if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
|
if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
|
||||||
if (UnaryOp->getOpcode() == UO_AddrOf) {
|
if (UnaryOp->getOpcode() == UO_AddrOf)
|
||||||
Fixit = FixItHint::CreateRemoval(
|
|
||||||
CharSourceRange::getTokenRange(SizeOfArg->getLocStart(),
|
|
||||||
SizeOfArg->getLocStart()));
|
|
||||||
ActionIdx = 1; // If its an address-of operator, just remove it.
|
ActionIdx = 1; // If its an address-of operator, just remove it.
|
||||||
}
|
|
||||||
if (Context.getTypeSize(PointeeTy) == Context.getCharWidth())
|
if (Context.getTypeSize(PointeeTy) == Context.getCharWidth())
|
||||||
ActionIdx = 2; // If the pointee's size is sizeof(char),
|
ActionIdx = 2; // If the pointee's size is sizeof(char),
|
||||||
// suggest an explicit length.
|
// suggest an explicit length.
|
||||||
unsigned DestSrcSelect =
|
|
||||||
(BId == Builtin::BIstrndup ? 1 : ArgIdx);
|
|
||||||
|
|
||||||
// If the function is defined as a builtin macro, do not show macro
|
// If the function is defined as a builtin macro, do not show macro
|
||||||
// expansion.
|
// expansion.
|
||||||
|
@ -2790,14 +2780,18 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
|
||||||
SM.getSpellingLoc(SSR.getEnd()));
|
SM.getSpellingLoc(SSR.getEnd()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DiagRuntimeBehavior(SL, Dest,
|
DiagRuntimeBehavior(SL, SizeOfArg,
|
||||||
PDiag(diag::warn_sizeof_pointer_expr_memaccess)
|
PDiag(diag::warn_sizeof_pointer_expr_memaccess)
|
||||||
<< ReadableName
|
<< ReadableName
|
||||||
<< DestSrcSelect
|
<< PointeeTy
|
||||||
<< ActionIdx
|
<< DestTy
|
||||||
<< DSR
|
<< DSR
|
||||||
<< SSR
|
<< SSR);
|
||||||
<< Fixit);
|
DiagRuntimeBehavior(SL, SizeOfArg,
|
||||||
|
PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
|
||||||
|
<< ActionIdx
|
||||||
|
<< SSR);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
// RUN: cp %s %t
|
|
||||||
// RUN: not %clang_cc1 -fixit -Werror -x c++ -std=c++98 %t
|
|
||||||
// RUN: %clang_cc1 -fsyntax-only -Werror -x c++ -std=c++98 %t
|
|
||||||
// RUN: cp %s %t
|
|
||||||
// RUN: not %clang_cc1 -DUSE_BUILTINS -fixit -Werror -x c++ -std=c++98 %t
|
|
||||||
// RUN: %clang_cc1 -DUSE_BUILTINS -fsyntax-only -Werror -x c++ -std=c++98 %t
|
|
||||||
|
|
||||||
extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
|
|
||||||
|
|
||||||
#ifdef USE_BUILTINS
|
|
||||||
# define BUILTIN(f) __builtin_ ## f
|
|
||||||
#else
|
|
||||||
# define BUILTIN(f) f
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define memcpy BUILTIN(memcpy)
|
|
||||||
|
|
||||||
int testFixits(int *to, int *from) {
|
|
||||||
memcpy(to, from, sizeof(to)); // \
|
|
||||||
// expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination; did you mean to dereference it?}}
|
|
||||||
memcpy(0, &from, sizeof(&from)); // \
|
|
||||||
// expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source; did you mean to remove the addressof?}}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -35,27 +35,27 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
|
||||||
|
|
||||||
/* Should warn */
|
/* Should warn */
|
||||||
memset(&s, 0, sizeof(&s)); // \
|
memset(&s, 0, sizeof(&s)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
|
// expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
memset(ps, 0, sizeof(ps)); // \
|
memset(ps, 0, sizeof(ps)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
|
// expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
memset(ps2, 0, sizeof(ps2)); // \
|
memset(ps2, 0, sizeof(ps2)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
|
// expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
memset(ps2, 0, sizeof(typeof(ps2))); // \
|
memset(ps2, 0, sizeof(typeof(ps2))); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
|
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
|
||||||
memset(ps2, 0, sizeof(PS)); // \
|
memset(ps2, 0, sizeof(PS)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
|
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
|
||||||
memset(heap_buffer, 0, sizeof(heap_buffer)); // \
|
memset(heap_buffer, 0, sizeof(heap_buffer)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
|
// expected-warning {{'memset' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
|
||||||
|
|
||||||
memcpy(&s, 0, sizeof(&s)); // \
|
memcpy(&s, 0, sizeof(&s)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination}}
|
// expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
memcpy(0, &s, sizeof(&s)); // \
|
memcpy(0, &s, sizeof(&s)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}}
|
// expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
|
|
||||||
memmove(ps, 0, sizeof(ps)); // \
|
memmove(ps, 0, sizeof(ps)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memmove' call is the same expression as the destination}}
|
// expected-warning {{'memmove' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
memcmp(ps, 0, sizeof(ps)); // \
|
memcmp(ps, 0, sizeof(ps)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'memcmp' call is the same expression as the destination}}
|
// expected-warning {{'memcmp' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
|
||||||
|
|
||||||
/* Shouldn't warn */
|
/* Shouldn't warn */
|
||||||
memset((void*)&s, 0, sizeof(&s));
|
memset((void*)&s, 0, sizeof(&s));
|
||||||
|
@ -132,14 +132,14 @@ void strcpy_and_friends() {
|
||||||
const char* BAR = "<- this, too";
|
const char* BAR = "<- this, too";
|
||||||
|
|
||||||
strncmp(FOO, BAR, sizeof(FOO)); // \
|
strncmp(FOO, BAR, sizeof(FOO)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'strncmp' call is the same expression as the destination}}
|
// expected-warning {{'strncmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
|
||||||
strncasecmp(FOO, BAR, sizeof(FOO)); // \
|
strncasecmp(FOO, BAR, sizeof(FOO)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'strncasecmp' call is the same expression as the destination}}
|
// expected-warning {{'strncasecmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
|
||||||
|
|
||||||
char buff[80];
|
char buff[80];
|
||||||
|
|
||||||
strncpy(buff, BAR, sizeof(BAR)); // \
|
strncpy(buff, BAR, sizeof(BAR)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'strncpy' call is the same expression as the source}}
|
// expected-warning {{'strncpy' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
|
||||||
strndup(FOO, sizeof(FOO)); // \
|
strndup(FOO, sizeof(FOO)); // \
|
||||||
// expected-warning {{argument to 'sizeof' in 'strndup' call is the same expression as the source}}
|
// expected-warning {{'strndup' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче