// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -fsyntax-only %s -Wdouble-promotion // RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -fsyntax-only -x c++ %s -Wdouble-promotion float ReturnFloatFromDouble(double d) { return d; } float ReturnFloatFromLongDouble(long double ld) { return ld; } double ReturnDoubleFromLongDouble(long double ld) { return ld; } double ReturnDoubleFromFloat(float f) { return f; //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} } long double ReturnLongDoubleFromFloat(float f) { return f; //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} } long double ReturnLongDoubleFromDouble(double d) { return d; //expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} } double ReturnDoubleFromFloatWithExplicitCast(float f) { return (double)f; } long double ReturnLongDoubleFromFloatWithExplicitCast(float f) { return (long double)f; } long double ReturnLongDoubleFromDoubleWithExplicitCast(double d) { return (long double)d; } void Assignment(float f, double d, long double ld) { d = f; //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} ld = f; //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} ld = d; //expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} d = (double)f; ld = (long double)f; ld = (long double)d; f = d; f = ld; d = ld; } void AssignmentWithExtraParens(float f, double d, long double ld) { d = (f); //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} ld = (f); //expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} ld = (d); //expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} d = (double)(f); ld = (long double)(f); ld = (long double)(d); } extern void DoubleParameter(double); extern void LongDoubleParameter(long double); void ArgumentPassing(float f, double d) { DoubleParameter(f); // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} LongDoubleParameter(f); // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} LongDoubleParameter(d); // expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} DoubleParameter((double)f); LongDoubleParameter((long double)f); LongDoubleParameter((long double)d); } void BinaryOperator(float f, double d, long double ld) { f = f * d; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} f = d * f; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} f = f * ld; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} f = ld * f; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} d = d * ld; // expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} d = ld * d; // expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} f = (double)f * d; f = d * (double)f; f = (long double)f * ld; f = ld * (long double)f; d = (long double)d * ld; d = ld * (long double)d; } void MultiplicationAssignment(float f, double d, long double ld) { d *= f; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'double'}} ld *= f; // expected-warning{{implicit conversion increases floating-point precision: 'float' to 'long double'}} ld *= d; // expected-warning{{implicit conversion increases floating-point precision: 'double' to 'long double'}} d *= (double)f; ld *= (long double)f; ld *= (long double)d; // FIXME: These cases should produce warnings as above. f *= d; f *= ld; d *= ld; } // FIXME: As with a binary operator, the operands to the conditional operator are // converted to a common type and should produce a warning. void ConditionalOperator(float f, double d, long double ld, int i) { f = i ? f : d; f = i ? d : f; f = i ? f : ld; f = i ? ld : f; d = i ? d : ld; d = i ? ld : d; }