kpn created this revision. kpn added a reviewer: rsmith. Herald added a reviewer: javed.absar. Herald added a subscriber: cfe-commits.
The UnaryOperator needs to know about #pragma FENV_ACCESS to eventually properly emit the constrained math intrinsics. This diff just gets the information about the pragma into that part of the AST. The visible behavior of clang is unaffected and so this cannot yet be tested. Repository: rC Clang https://reviews.llvm.org/D52839 Files: include/clang/AST/Expr.h lib/AST/ASTImporter.cpp lib/Analysis/BodyFarm.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CGStmtOpenMP.cpp lib/Frontend/Rewrite/RewriteModernObjC.cpp lib/Frontend/Rewrite/RewriteObjC.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaPseudoObject.cpp
Index: lib/Sema/SemaPseudoObject.cpp =================================================================== --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -133,7 +133,8 @@ uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(), - uop->canOverflow()); + uop->canOverflow(), + FPOptions()); } if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { @@ -543,7 +544,7 @@ !resultType->isDependentType() ? S.Context.getTypeSize(resultType) >= S.Context.getTypeSize(S.Context.IntTy) - : false); + : false, FPOptions()); return complete(syntactic); } @@ -1564,7 +1565,8 @@ // Do nothing if the operand is dependent. if (op->isTypeDependent()) return new (Context) UnaryOperator(op, opcode, Context.DependentTy, - VK_RValue, OK_Ordinary, opcLoc, false); + VK_RValue, OK_Ordinary, opcLoc, false, + FPOptions()); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); @@ -1650,7 +1652,8 @@ Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); return new (Context) UnaryOperator( op, uop->getOpcode(), uop->getType(), uop->getValueKind(), - uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow()); + uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(), + FPOptions()); } else if (CompoundAssignOperator *cop = dyn_cast<CompoundAssignOperator>(syntax)) { Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -12146,7 +12146,8 @@ if (Input->isTypeDependent()) { if (Fns.empty()) return new (Context) UnaryOperator(Input, Opc, Context.DependentTy, - VK_RValue, OK_Ordinary, OpLoc, false); + VK_RValue, OK_Ordinary, OpLoc, false, + FPFeatures); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators UnresolvedLookupExpr *Fn @@ -13671,7 +13672,8 @@ return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, - UnOp->getOperatorLoc(), false); + UnOp->getOperatorLoc(), false, + FPFeatures); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), @@ -13682,7 +13684,8 @@ return new (Context) UnaryOperator(SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), VK_RValue, OK_Ordinary, - UnOp->getOperatorLoc(), false); + UnOp->getOperatorLoc(), false, + FPFeatures); } // C++ [except.spec]p17: Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -4307,7 +4307,8 @@ Expr *sub = stripARCUnbridgedCast(uo->getSubExpr()); return new (Context) UnaryOperator(sub, UO_Extension, sub->getType(), sub->getValueKind(), - sub->getObjectKind(), uo->getOperatorLoc(), false); + sub->getObjectKind(), uo->getOperatorLoc(), false, + FPFeatures); } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { assert(!gse->isResultDependent()); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -12813,7 +12813,8 @@ CheckArrayAccess(Input.get()); auto *UO = new (Context) - UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow); + UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow, + FPFeatures); // Convert the result back to a half vector. if (ConvertHalfVec) return convertVector(UO, Context.HalfTy, *this); Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -11440,11 +11440,11 @@ Expr *From = FromB.build(S, Loc); From = new (S.Context) UnaryOperator(From, UO_AddrOf, S.Context.getPointerType(From->getType()), - VK_RValue, OK_Ordinary, Loc, false); + VK_RValue, OK_Ordinary, Loc, false, FPOptions()); Expr *To = ToB.build(S, Loc); To = new (S.Context) UnaryOperator(To, UO_AddrOf, S.Context.getPointerType(To->getType()), - VK_RValue, OK_Ordinary, Loc, false); + VK_RValue, OK_Ordinary, Loc, false, FPOptions()); const Type *E = T->getBaseElementTypeUnsafe(); bool NeedsCollectableMemCpy = @@ -11688,7 +11688,8 @@ // bound. Expr *Increment = new (S.Context) UnaryOperator(IterationVarRef.build(S, Loc), UO_PreInc, SizeType, - VK_LValue, OK_Ordinary, Loc, Upper.isMaxValue()); + VK_LValue, OK_Ordinary, Loc, Upper.isMaxValue(), + FPOptions()); // Construct the loop that copies all elements of this array. return S.ActOnForStmt( Index: lib/Frontend/Rewrite/RewriteObjC.cpp =================================================================== --- lib/Frontend/Rewrite/RewriteObjC.cpp +++ lib/Frontend/Rewrite/RewriteObjC.cpp @@ -2511,7 +2511,8 @@ Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -2712,7 +2713,8 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2730,7 +2732,8 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); } MsgExprs.push_back(SuperRep); break; @@ -2806,7 +2809,7 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, FPOptions()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3045,7 +3048,8 @@ VK_LValue, SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + VK_RValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -3875,7 +3879,8 @@ return DRE; Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), VK_LValue, OK_Ordinary, - DRE->getLocation(), false); + DRE->getLocation(), false, + FPOptions()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -4438,7 +4443,7 @@ UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, FPOptions()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -4457,7 +4462,7 @@ QT = Context->getPointerType(QT); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, OK_Ordinary, SourceLocation(), - false); + false, FPOptions()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -4474,7 +4479,7 @@ QT = Context->getPointerType(QT); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, OK_Ordinary, SourceLocation(), - false); + false, FPOptions()); } } InitExprs.push_back(Exp); @@ -4513,7 +4518,7 @@ if (!isNestedCapturedVar) Exp = new (Context) UnaryOperator( Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, - OK_Ordinary, SourceLocation(), false); + OK_Ordinary, SourceLocation(), false, FPOptions()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -4531,7 +4536,8 @@ FType, VK_LValue, SourceLocation()); NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + VK_RValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); Index: lib/Frontend/Rewrite/RewriteModernObjC.cpp =================================================================== --- lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -2589,7 +2589,8 @@ Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -3294,7 +3295,8 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3312,7 +3314,8 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); } MsgExprs.push_back(SuperRep); break; @@ -3388,7 +3391,7 @@ SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, FPOptions()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -4719,7 +4722,8 @@ return DRE; Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), VK_LValue, OK_Ordinary, - DRE->getLocation(), false); + DRE->getLocation(), false, + FPOptions()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5313,7 +5317,7 @@ UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, FPOptions()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5332,7 +5336,7 @@ QT = Context->getPointerType(QT); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, OK_Ordinary, SourceLocation(), - false); + false, FPOptions()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -5349,7 +5353,7 @@ QT = Context->getPointerType(QT); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, OK_Ordinary, SourceLocation(), - false); + false, FPOptions()); } } @@ -5390,7 +5394,7 @@ Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, SourceLocation(), - false); + false, FPOptions()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5416,7 +5420,8 @@ NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + VK_RValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); // Put Paren around the call. @@ -7560,7 +7565,8 @@ Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT, VK_LValue, OK_Ordinary, - SourceLocation(), false); + SourceLocation(), false, + FPOptions()); PE = new (Context) ParenExpr(OldRange.getBegin(), OldRange.getEnd(), Exp); Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -2514,7 +2514,7 @@ OK_Ordinary, S.getBeginLoc(), FPOptions()); // Increment for loop counter. UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, - S.getBeginLoc(), true); + S.getBeginLoc(), true, FPOptions()); auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) { // Iterate through all sections and emit a switch construct: // switch (IV) { Index: lib/CodeGen/CGObjC.cpp =================================================================== --- lib/CodeGen/CGObjC.cpp +++ lib/CodeGen/CGObjC.cpp @@ -3267,12 +3267,14 @@ DeclRefExpr DstExpr(&DstDecl, false, DestTy, VK_RValue, SourceLocation()); UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(), - VK_LValue, OK_Ordinary, SourceLocation(), false); + VK_LValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), - VK_LValue, OK_Ordinary, SourceLocation(), false); + VK_LValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); Expr *Args[2] = { &DST, &SRC }; CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment()); @@ -3350,7 +3352,8 @@ VK_RValue, SourceLocation()); UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), - VK_LValue, OK_Ordinary, SourceLocation(), false); + VK_LValue, OK_Ordinary, SourceLocation(), false, + FPOptions()); CXXConstructExpr *CXXConstExpr = cast<CXXConstructExpr>(PID->getGetterCXXConstructor()); Index: lib/Analysis/BodyFarm.cpp =================================================================== --- lib/Analysis/BodyFarm.cpp +++ lib/Analysis/BodyFarm.cpp @@ -150,7 +150,7 @@ UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) { return new (C) UnaryOperator(const_cast<Expr*>(Arg), UO_Deref, Ty, VK_LValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/ false); + /*CanOverflow*/ false, FPOptions()); } ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) { @@ -457,7 +457,8 @@ /* QualType=*/ C.IntTy, /* ExprValueKind=*/ VK_RValue, /* ExprObjectKind=*/ OK_Ordinary, SourceLocation(), - /* CanOverflow*/ false); + /* CanOverflow*/ false, + FPOptions()); // Create assignment. BinaryOperator *FlagAssignment = M.makeAssignment( @@ -522,7 +523,7 @@ Expr *DoneValue = new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy, VK_RValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/false); + /*CanOverflow*/false, FPOptions()); BinaryOperator *B = M.makeAssignment( Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -5834,7 +5834,8 @@ return new (Importer.getToContext()) UnaryOperator( SubExpr, E->getOpcode(), T, E->getValueKind(), E->getObjectKind(), - Importer.Import(E->getOperatorLoc()), E->canOverflow()); + Importer.Import(E->getOperatorLoc()), E->canOverflow(), + E->getFPFeatures()); } Expr * Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -1790,16 +1790,23 @@ unsigned CanOverflow : 1; SourceLocation Loc; Stmt *Val; + + // This is only meaningful for operations on floating point types and 0 + // otherwise. + unsigned FPFeatures : 3; + public: UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, - ExprObjectKind OK, SourceLocation l, bool CanOverflow) + ExprObjectKind OK, SourceLocation l, bool CanOverflow, + FPOptions FPFeatures) : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), input->isValueDependent(), (input->isInstantiationDependent() || type->isInstantiationDependentType()), input->containsUnexpandedParameterPack()), - Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input) {} + Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input), + FPFeatures(FPFeatures.getInt()) {} /// Build an empty unary operator. explicit UnaryOperator(EmptyShell Empty) @@ -1890,6 +1897,18 @@ const_child_range children() const { return const_child_range(&Val, &Val + 1); } + + // Set the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); } + + FPOptions getFPFeatures() const { return FPOptions(FPFeatures); } + + // Get the FENV_ACCESS status of this operator. Only meaningful for + // operations on floating point types. + bool isFEnvAccessOn() const { + return FPOptions(FPFeatures).allowFEnvAccess(); + } }; /// Helper class for OffsetOfExpr.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits