// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s void clang_analyzer_eval(bool); struct X0 { }; bool operator==(const X0&, const X0&); // PR7287 struct test { int a[2]; }; void t2() { test p = {{1,2}}; test q; q = p; } bool PR7287(X0 a, X0 b) { return operator==(a, b); } // Inlining non-static member operators mistakenly treated 'this' as the first // argument for a while. struct IntComparable { bool operator==(int x) const { return x == 0; } }; void testMemberOperator(IntComparable B) { clang_analyzer_eval(B == 0); // expected-warning{{TRUE}} } namespace UserDefinedConversions { class Convertible { public: operator int() const { return 42; } operator bool() const { return true; } }; void test(const Convertible &obj) { clang_analyzer_eval((int)obj == 42); // expected-warning{{TRUE}} clang_analyzer_eval(obj); // expected-warning{{TRUE}} } } namespace RValues { struct SmallOpaque { float x; int operator +() const { return (int)x; } }; struct LargeOpaque { float x[4]; int operator +() const { return (int)x[0]; } }; SmallOpaque getSmallOpaque() { SmallOpaque obj; obj.x = 1.0; return obj; } LargeOpaque getLargeOpaque() { LargeOpaque obj = LargeOpaque(); obj.x[0] = 1.0; return obj; } void test(int coin) { // Force a cache-out when we try to conjure a temporary region for the operator call. // ...then, don't crash. clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}} clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}} } } namespace SynthesizedAssignment { struct A { int a; A& operator=(A& other) { a = -other.a; return *this; } A& operator=(A&& other) { a = other.a+1; return *this; } }; struct B { int x; A a[3]; B& operator=(B&) = default; B& operator=(B&&) = default; }; // This used to produce a warning about the iteration variable in the // synthesized assignment operator being undefined. void testNoWarning() { B v, u; u = v; } void testNoWarningMove() { B v, u; u = static_cast<B &&>(v); } void testConsistency() { B v, u; v.a[1].a = 47; v.a[2].a = 42; u = v; clang_analyzer_eval(u.a[1].a == -47); // expected-warning{{TRUE}} clang_analyzer_eval(u.a[2].a == -42); // expected-warning{{TRUE}} } void testConsistencyMove() { B v, u; v.a[1].a = 47; v.a[2].a = 42; u = static_cast<B &&>(v); clang_analyzer_eval(u.a[1].a == 48); // expected-warning{{TRUE}} clang_analyzer_eval(u.a[2].a == 43); // expected-warning{{TRUE}} } }