// RUN: %clang_cc1 -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}} } }