zequanwu created this revision. zequanwu added reviewers: rsmith, rnk. zequanwu added a project: clang. Herald added a subscriber: cfe-commits.
bug filed here: https://bugs.llvm.org/show_bug.cgi?id=45624 Uninitialized variable as function const reference parameter should be use. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D79895 Files: clang/lib/Analysis/UninitializedValues.cpp clang/test/SemaCXX/uninit-variables.cpp clang/test/SemaCXX/uninitialized.cpp Index: clang/test/SemaCXX/uninitialized.cpp =================================================================== --- clang/test/SemaCXX/uninitialized.cpp +++ clang/test/SemaCXX/uninitialized.cpp @@ -59,13 +59,13 @@ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}} int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + int j = far(j); // expected-warning {{variable 'j' is uninitialized when used within its own initialization}} // These don't warn as they don't require the value. int g = sizeof(g); void* ptr = &ptr; int h = bar(&h); int i = boo(i); - int j = far(j); int k = __alignof__(k); int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} @@ -93,13 +93,13 @@ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}} int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + int j = far(j); // expected-warning {{variable 'j' is uninitialized when used within its own initialization}} // These don't warn as they don't require the value. int g = sizeof(g); void* ptr = &ptr; int h = bar(&h); int i = boo(i); - int j = far(j); int k = __alignof__(k); int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} @@ -284,8 +284,8 @@ A a34(std::move(a34)); // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}} A a35 = std::move(x ? a34 : (37, a35)); // expected-warning {{variable 'a35' is uninitialized when used within its own initialization}} - A a36 = const_refA(a36); - A a37(const_refA(a37)); + A a36 = const_refA(a36); // expected-warning {{variable 'a36' is uninitialized when used within its own initialization}} + A a37(const_refA(a37)); // expected-warning {{variable 'a37' is uninitialized when used within its own initialization}} A a38({a38}); // expected-warning {{variable 'a38' is uninitialized when used within its own initialization}} A a39 = {a39}; // expected-warning {{variable 'a39' is uninitialized when used within its own initialization}} @@ -294,9 +294,9 @@ A a41 = !a41; // expected-warning {{variable 'a41' is uninitialized when used within its own initialization}} A a42 = !(a42); // expected-warning {{variable 'a42' is uninitialized when used within its own initialization}} A a43 = a43 != a42; // expected-warning {{variable 'a43' is uninitialized when used within its own initialization}} - A a44 = a43 != a44; // expected-warning {{variable 'a44' is uninitialized when used within its own initialization}} + A a44 = a43 != a44; // expected-warning 2{{variable 'a44' is uninitialized when used within its own initialization}} A a45 = a45 != a45; // expected-warning 2{{variable 'a45' is uninitialized when used within its own initialization}} - A a46 = 0 != a46; // expected-warning {{variable 'a46' is uninitialized when used within its own initialization}} + A a46 = 0 != a46; // expected-warning 2{{variable 'a46' is uninitialized when used within its own initialization}} A a47(a47.set(a47.num)); // expected-warning 2{{variable 'a47' is uninitialized when used within its own initialization}} A a48(a47.set(a48.num)); // expected-warning {{variable 'a48' is uninitialized when used within its own initialization}} Index: clang/test/SemaCXX/uninit-variables.cpp =================================================================== --- clang/test/SemaCXX/uninit-variables.cpp +++ clang/test/SemaCXX/uninit-variables.cpp @@ -144,8 +144,8 @@ void consume_const_ref(const int &n); int test_const_ref() { int n; // expected-note {{variable}} - consume_const_ref(n); - return n; // expected-warning {{uninitialized when used here}} + consume_const_ref(n); // expected-warning {{variable 'n' is uninitialized when used here}} + return n; } // Don't crash here. Index: clang/lib/Analysis/UninitializedValues.cpp =================================================================== --- clang/lib/Analysis/UninitializedValues.cpp +++ clang/lib/Analysis/UninitializedValues.cpp @@ -413,14 +413,16 @@ return; } - // If a value is passed by const pointer or by const reference to a function, + // If a value is passed by const pointer to a function, // we should not assume that it is initialized by the call, and we // conservatively do not assume that it is used. + // If a value is passed by const reference to a function, + // it should already be initialized. for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) { if ((*I)->isGLValue()) { if ((*I)->getType().isConstQualified()) - classify((*I), Ignore); + classify((*I), Use); } else if (isPointerToConst((*I)->getType())) { const Expr *Ex = stripCasts(DC->getParentASTContext(), *I); const auto *UO = dyn_cast<UnaryOperator>(Ex);
Index: clang/test/SemaCXX/uninitialized.cpp =================================================================== --- clang/test/SemaCXX/uninitialized.cpp +++ clang/test/SemaCXX/uninitialized.cpp @@ -59,13 +59,13 @@ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}} int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + int j = far(j); // expected-warning {{variable 'j' is uninitialized when used within its own initialization}} // These don't warn as they don't require the value. int g = sizeof(g); void* ptr = &ptr; int h = bar(&h); int i = boo(i); - int j = far(j); int k = __alignof__(k); int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} @@ -93,13 +93,13 @@ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}} int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} + int j = far(j); // expected-warning {{variable 'j' is uninitialized when used within its own initialization}} // These don't warn as they don't require the value. int g = sizeof(g); void* ptr = &ptr; int h = bar(&h); int i = boo(i); - int j = far(j); int k = __alignof__(k); int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}} @@ -284,8 +284,8 @@ A a34(std::move(a34)); // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}} A a35 = std::move(x ? a34 : (37, a35)); // expected-warning {{variable 'a35' is uninitialized when used within its own initialization}} - A a36 = const_refA(a36); - A a37(const_refA(a37)); + A a36 = const_refA(a36); // expected-warning {{variable 'a36' is uninitialized when used within its own initialization}} + A a37(const_refA(a37)); // expected-warning {{variable 'a37' is uninitialized when used within its own initialization}} A a38({a38}); // expected-warning {{variable 'a38' is uninitialized when used within its own initialization}} A a39 = {a39}; // expected-warning {{variable 'a39' is uninitialized when used within its own initialization}} @@ -294,9 +294,9 @@ A a41 = !a41; // expected-warning {{variable 'a41' is uninitialized when used within its own initialization}} A a42 = !(a42); // expected-warning {{variable 'a42' is uninitialized when used within its own initialization}} A a43 = a43 != a42; // expected-warning {{variable 'a43' is uninitialized when used within its own initialization}} - A a44 = a43 != a44; // expected-warning {{variable 'a44' is uninitialized when used within its own initialization}} + A a44 = a43 != a44; // expected-warning 2{{variable 'a44' is uninitialized when used within its own initialization}} A a45 = a45 != a45; // expected-warning 2{{variable 'a45' is uninitialized when used within its own initialization}} - A a46 = 0 != a46; // expected-warning {{variable 'a46' is uninitialized when used within its own initialization}} + A a46 = 0 != a46; // expected-warning 2{{variable 'a46' is uninitialized when used within its own initialization}} A a47(a47.set(a47.num)); // expected-warning 2{{variable 'a47' is uninitialized when used within its own initialization}} A a48(a47.set(a48.num)); // expected-warning {{variable 'a48' is uninitialized when used within its own initialization}} Index: clang/test/SemaCXX/uninit-variables.cpp =================================================================== --- clang/test/SemaCXX/uninit-variables.cpp +++ clang/test/SemaCXX/uninit-variables.cpp @@ -144,8 +144,8 @@ void consume_const_ref(const int &n); int test_const_ref() { int n; // expected-note {{variable}} - consume_const_ref(n); - return n; // expected-warning {{uninitialized when used here}} + consume_const_ref(n); // expected-warning {{variable 'n' is uninitialized when used here}} + return n; } // Don't crash here. Index: clang/lib/Analysis/UninitializedValues.cpp =================================================================== --- clang/lib/Analysis/UninitializedValues.cpp +++ clang/lib/Analysis/UninitializedValues.cpp @@ -413,14 +413,16 @@ return; } - // If a value is passed by const pointer or by const reference to a function, + // If a value is passed by const pointer to a function, // we should not assume that it is initialized by the call, and we // conservatively do not assume that it is used. + // If a value is passed by const reference to a function, + // it should already be initialized. for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) { if ((*I)->isGLValue()) { if ((*I)->getType().isConstQualified()) - classify((*I), Ignore); + classify((*I), Use); } else if (isPointerToConst((*I)->getType())) { const Expr *Ex = stripCasts(DC->getParentASTContext(), *I); const auto *UO = dyn_cast<UnaryOperator>(Ex);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits