aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-06-15 07:32:55 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-06-15 07:32:55 +0000
commit43ad182474fac1e9d68ea4d1bcb80f8f9720245d (patch)
treed4ab4cf4f6cdc4060d5c156b656ae54236901d58
parent88318139c94cef1a77cce969613bbc0745d7e99f (diff)
When analyzing for member self-assignment, don't attempt to dereference null
Stmt* such as those which occur in ?: . Fixes PR7378. Also, generally whip the code into shape fixing several coding style violations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105992 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp40
1 files changed, 21 insertions, 19 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 7dcda88407..aa2be17824 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1217,18 +1217,25 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
/// containing the field that is being initialized. Returns true if there is an
/// uninitialized field was used an updates the SourceLocation parameter; false
/// otherwise.
-static bool InitExprContainsUninitializedFields(const Stmt* S,
- const FieldDecl* LhsField,
- SourceLocation* L) {
- const MemberExpr* ME = dyn_cast<MemberExpr>(S);
- if (ME) {
- const NamedDecl* RhsField = ME->getMemberDecl();
+static bool InitExprContainsUninitializedFields(const Stmt *S,
+ const FieldDecl *LhsField,
+ SourceLocation *L) {
+ if (isa<CallExpr>(S)) {
+ // Do not descend into function calls or constructors, as the use
+ // of an uninitialized field may be valid. One would have to inspect
+ // the contents of the function/ctor to determine if it is safe or not.
+ // i.e. Pass-by-value is never safe, but pass-by-reference and pointers
+ // may be safe, depending on what the function/ctor does.
+ return false;
+ }
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
+ const NamedDecl *RhsField = ME->getMemberDecl();
if (RhsField == LhsField) {
// Initializing a field with itself. Throw a warning.
// But wait; there are exceptions!
// Exception #1: The field may not belong to this record.
// e.g. Foo(const Foo& rhs) : A(rhs.A) {}
- const Expr* base = ME->getBase();
+ const Expr *base = ME->getBase();
if (base != NULL && !isa<CXXThisExpr>(base->IgnoreParenCasts())) {
// Even though the field matches, it does not belong to this record.
return false;
@@ -1239,21 +1246,16 @@ static bool InitExprContainsUninitializedFields(const Stmt* S,
return true;
}
}
- bool found = false;
- for (Stmt::const_child_iterator it = S->child_begin();
- it != S->child_end() && found == false;
- ++it) {
- if (isa<CallExpr>(S)) {
- // Do not descend into function calls or constructors, as the use
- // of an uninitialized field may be valid. One would have to inspect
- // the contents of the function/ctor to determine if it is safe or not.
- // i.e. Pass-by-value is never safe, but pass-by-reference and pointers
- // may be safe, depending on what the function/ctor does.
+ for (Stmt::const_child_iterator it = S->child_begin(), e = S->child_end();
+ it != e; ++it) {
+ if (!*it) {
+ // An expression such as 'member(arg ?: "")' may trigger this.
continue;
}
- found = InitExprContainsUninitializedFields(*it, LhsField, L);
+ if (InitExprContainsUninitializedFields(*it, LhsField, L))
+ return true;
}
- return found;
+ return false;
}
Sema::MemInitResult