diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-12-02 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-12-02 19:20:19 +0000 |
commit | 545937e1be2eb318dc3c8db284ab27a64c51c773 (patch) | |
tree | 2094a515cd4d327c4154dddf013798d1b7737209 /lib/Sema | |
parent | 17c7957f023f02fc2c88f51f8908c19b52609275 (diff) | |
download | src-test2-545937e1be2eb318dc3c8db284ab27a64c51c773.tar.gz src-test2-545937e1be2eb318dc3c8db284ab27a64c51c773.zip |
Notes
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 198 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 14 |
2 files changed, 204 insertions, 8 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index b8e7ede2716c..7f7dbe8873d4 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1454,8 +1454,17 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, return SemaBuiltinConstantArgRange(TheCall, i, l, u + l); } +// CheckMipsBuiltinFunctionCall - Checks the constant value passed to the +// intrinsic is correct. The switch statement is ordered by DSP, MSA. The +// ordering for DSP is unspecified. MSA is ordered by the data format used +// by the underlying instruction i.e., df/m, df/n and then by size. +// +// FIXME: The size tests here should instead be tablegen'd along with the +// definitions from include/clang/Basic/BuiltinsMips.def. +// FIXME: GCC is strict on signedness for some of these intrinsics, we should +// be too. bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - unsigned i = 0, l = 0, u = 0; + unsigned i = 0, l = 0, u = 0, m = 0; switch (BuiltinID) { default: return false; case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; @@ -1465,9 +1474,168 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; - } - - return SemaBuiltinConstantArgRange(TheCall, i, l, u); + // MSA instrinsics. Instructions (which the intrinsics maps to) which use the + // df/m field. + // These intrinsics take an unsigned 3 bit immediate. + case Mips::BI__builtin_msa_bclri_b: + case Mips::BI__builtin_msa_bnegi_b: + case Mips::BI__builtin_msa_bseti_b: + case Mips::BI__builtin_msa_sat_s_b: + case Mips::BI__builtin_msa_sat_u_b: + case Mips::BI__builtin_msa_slli_b: + case Mips::BI__builtin_msa_srai_b: + case Mips::BI__builtin_msa_srari_b: + case Mips::BI__builtin_msa_srli_b: + case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; + case Mips::BI__builtin_msa_binsli_b: + case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; + // These intrinsics take an unsigned 4 bit immediate. + case Mips::BI__builtin_msa_bclri_h: + case Mips::BI__builtin_msa_bnegi_h: + case Mips::BI__builtin_msa_bseti_h: + case Mips::BI__builtin_msa_sat_s_h: + case Mips::BI__builtin_msa_sat_u_h: + case Mips::BI__builtin_msa_slli_h: + case Mips::BI__builtin_msa_srai_h: + case Mips::BI__builtin_msa_srari_h: + case Mips::BI__builtin_msa_srli_h: + case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; + case Mips::BI__builtin_msa_binsli_h: + case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; + // These intrinsics take an unsigned 5 bit immedate. + // The first block of intrinsics actually have an unsigned 5 bit field, + // not a df/n field. + case Mips::BI__builtin_msa_clei_u_b: + case Mips::BI__builtin_msa_clei_u_h: + case Mips::BI__builtin_msa_clei_u_w: + case Mips::BI__builtin_msa_clei_u_d: + case Mips::BI__builtin_msa_clti_u_b: + case Mips::BI__builtin_msa_clti_u_h: + case Mips::BI__builtin_msa_clti_u_w: + case Mips::BI__builtin_msa_clti_u_d: + case Mips::BI__builtin_msa_maxi_u_b: + case Mips::BI__builtin_msa_maxi_u_h: + case Mips::BI__builtin_msa_maxi_u_w: + case Mips::BI__builtin_msa_maxi_u_d: + case Mips::BI__builtin_msa_mini_u_b: + case Mips::BI__builtin_msa_mini_u_h: + case Mips::BI__builtin_msa_mini_u_w: + case Mips::BI__builtin_msa_mini_u_d: + case Mips::BI__builtin_msa_addvi_b: + case Mips::BI__builtin_msa_addvi_h: + case Mips::BI__builtin_msa_addvi_w: + case Mips::BI__builtin_msa_addvi_d: + case Mips::BI__builtin_msa_bclri_w: + case Mips::BI__builtin_msa_bnegi_w: + case Mips::BI__builtin_msa_bseti_w: + case Mips::BI__builtin_msa_sat_s_w: + case Mips::BI__builtin_msa_sat_u_w: + case Mips::BI__builtin_msa_slli_w: + case Mips::BI__builtin_msa_srai_w: + case Mips::BI__builtin_msa_srari_w: + case Mips::BI__builtin_msa_srli_w: + case Mips::BI__builtin_msa_srlri_w: + case Mips::BI__builtin_msa_subvi_b: + case Mips::BI__builtin_msa_subvi_h: + case Mips::BI__builtin_msa_subvi_w: + case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; + case Mips::BI__builtin_msa_binsli_w: + case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; + // These intrinsics take an unsigned 6 bit immediate. + case Mips::BI__builtin_msa_bclri_d: + case Mips::BI__builtin_msa_bnegi_d: + case Mips::BI__builtin_msa_bseti_d: + case Mips::BI__builtin_msa_sat_s_d: + case Mips::BI__builtin_msa_sat_u_d: + case Mips::BI__builtin_msa_slli_d: + case Mips::BI__builtin_msa_srai_d: + case Mips::BI__builtin_msa_srari_d: + case Mips::BI__builtin_msa_srli_d: + case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; + case Mips::BI__builtin_msa_binsli_d: + case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; + // These intrinsics take a signed 5 bit immediate. + case Mips::BI__builtin_msa_ceqi_b: + case Mips::BI__builtin_msa_ceqi_h: + case Mips::BI__builtin_msa_ceqi_w: + case Mips::BI__builtin_msa_ceqi_d: + case Mips::BI__builtin_msa_clti_s_b: + case Mips::BI__builtin_msa_clti_s_h: + case Mips::BI__builtin_msa_clti_s_w: + case Mips::BI__builtin_msa_clti_s_d: + case Mips::BI__builtin_msa_clei_s_b: + case Mips::BI__builtin_msa_clei_s_h: + case Mips::BI__builtin_msa_clei_s_w: + case Mips::BI__builtin_msa_clei_s_d: + case Mips::BI__builtin_msa_maxi_s_b: + case Mips::BI__builtin_msa_maxi_s_h: + case Mips::BI__builtin_msa_maxi_s_w: + case Mips::BI__builtin_msa_maxi_s_d: + case Mips::BI__builtin_msa_mini_s_b: + case Mips::BI__builtin_msa_mini_s_h: + case Mips::BI__builtin_msa_mini_s_w: + case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; + // These intrinsics take an unsigned 8 bit immediate. + case Mips::BI__builtin_msa_andi_b: + case Mips::BI__builtin_msa_nori_b: + case Mips::BI__builtin_msa_ori_b: + case Mips::BI__builtin_msa_shf_b: + case Mips::BI__builtin_msa_shf_h: + case Mips::BI__builtin_msa_shf_w: + case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; + case Mips::BI__builtin_msa_bseli_b: + case Mips::BI__builtin_msa_bmnzi_b: + case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; + // df/n format + // These intrinsics take an unsigned 4 bit immediate. + case Mips::BI__builtin_msa_copy_s_b: + case Mips::BI__builtin_msa_copy_u_b: + case Mips::BI__builtin_msa_insve_b: + case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; + case Mips::BI__builtin_msa_sld_b: + case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; + // These intrinsics take an unsigned 3 bit immediate. + case Mips::BI__builtin_msa_copy_s_h: + case Mips::BI__builtin_msa_copy_u_h: + case Mips::BI__builtin_msa_insve_h: + case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; + case Mips::BI__builtin_msa_sld_h: + case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; + // These intrinsics take an unsigned 2 bit immediate. + case Mips::BI__builtin_msa_copy_s_w: + case Mips::BI__builtin_msa_copy_u_w: + case Mips::BI__builtin_msa_insve_w: + case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; + case Mips::BI__builtin_msa_sld_w: + case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; + // These intrinsics take an unsigned 1 bit immediate. + case Mips::BI__builtin_msa_copy_s_d: + case Mips::BI__builtin_msa_copy_u_d: + case Mips::BI__builtin_msa_insve_d: + case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; + case Mips::BI__builtin_msa_sld_d: + case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; + // Memory offsets and immediate loads. + // These intrinsics take a signed 10 bit immediate. + case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 127; break; + case Mips::BI__builtin_msa_ldi_h: + case Mips::BI__builtin_msa_ldi_w: + case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; + case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 16; break; + case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 16; break; + case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 16; break; + case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 16; break; + case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 16; break; + case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 16; break; + case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 16; break; + case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 16; break; + } + + if (!m) + return SemaBuiltinConstantArgRange(TheCall, i, l, u); + + return SemaBuiltinConstantArgRange(TheCall, i, l, u) || + SemaBuiltinConstantArgMultiple(TheCall, i, m); } bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { @@ -3605,6 +3773,28 @@ bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, return false; } +/// SemaBuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr +/// TheCall is a constant expression is a multiple of Num.. +bool Sema::SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, + unsigned Num) { + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + if (Result.getSExtValue() % Num != 0) + return Diag(TheCall->getLocStart(), diag::err_argument_not_multiple) + << Num << Arg->getSourceRange(); + + return false; +} + /// SemaBuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr /// TheCall is an ARM/AArch64 special register string literal. bool Sema::SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 56f4019bfbb6..dfdd36752bf6 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4221,9 +4221,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, // A template constructor is never a copy constructor. // FIXME: However, it may actually be selected at the actual overload // resolution point. - if (isa<FunctionTemplateDecl>(ND)) + if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl())) continue; - const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND); + // UsingDecl itself is not a constructor + if (isa<UsingDecl>(ND)) + continue; + auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl()); if (Constructor->isCopyConstructor(FoundTQs)) { FoundConstructor = true; const FunctionProtoType *CPT @@ -4257,9 +4260,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, bool FoundConstructor = false; for (const auto *ND : Self.LookupConstructors(RD)) { // FIXME: In C++0x, a constructor template can be a default constructor. - if (isa<FunctionTemplateDecl>(ND)) + if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl())) + continue; + // UsingDecl itself is not a constructor + if (isa<UsingDecl>(ND)) continue; - const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND); + auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl()); if (Constructor->isDefaultConstructor()) { FoundConstructor = true; const FunctionProtoType *CPT |