//===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"

namespace llvm {
namespace {

TEST(VerifierTest, Branch_i1) {
  LLVMContext C;
  Module M("M", C);
  FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
  Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
  BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
  BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
  ReturnInst::Create(C, Exit);

  // To avoid triggering an assertion in BranchInst::Create, we first create
  // a branch with an 'i1' condition ...

  Constant *False = ConstantInt::getFalse(C);
  BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);

  // ... then use setOperand to redirect it to a value of different type.

  Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
  BI->setOperand(0, Zero32);

  EXPECT_TRUE(verifyFunction(*F));
}

TEST(VerifierTest, InvalidRetAttribute) {
  LLVMContext C;
  Module M("M", C);
  FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
  Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
  AttributeSet AS = F->getAttributes();
  F->setAttributes(AS.addAttribute(C, AttributeSet::ReturnIndex,
                                   Attribute::UWTable));

  std::string Error;
  raw_string_ostream ErrorOS(Error);
  EXPECT_TRUE(verifyModule(M, &ErrorOS));
  EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
      "Attribute 'uwtable' only applies to functions!"));
}

TEST(VerifierTest, CrossModuleRef) {
  LLVMContext C;
  Module M1("M1", C);
  Module M2("M2", C);
  Module M3("M3", C);
  FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
  Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy));
  Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy));
  Function *F3 = cast<Function>(M3.getOrInsertFunction("foo3", FTy));

  BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
  BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);

  // BAD: Referencing function in another module
  CallInst::Create(F2,"call",Entry1);

  // BAD: Referencing personality routine in another module
  F3->setPersonalityFn(F2);

  // Fill in the body
  Constant *ConstZero = ConstantInt::get(Type::getInt32Ty(C), 0);
  ReturnInst::Create(C, ConstZero, Entry1);
  ReturnInst::Create(C, ConstZero, Entry3);

  std::string Error;
  raw_string_ostream ErrorOS(Error);
  EXPECT_TRUE(verifyModule(M2, &ErrorOS));
  EXPECT_TRUE(StringRef(ErrorOS.str())
                  .equals("Global is used by function in a different module\n"
                          "i32 ()* @foo2\n"
                          "; ModuleID = 'M2'\n"
                          "i32 ()* @foo3\n"
                          "; ModuleID = 'M3'\n"
                          "Global is referenced in a different module!\n"
                          "i32 ()* @foo2\n"
                          "; ModuleID = 'M2'\n"
                          "  %call = call i32 @foo2()\n"
                          "i32 ()* @foo1\n"
                          "; ModuleID = 'M1'\n"));

  Error.clear();
  EXPECT_TRUE(verifyModule(M1, &ErrorOS));
  EXPECT_TRUE(StringRef(ErrorOS.str()).equals(
      "Referencing function in another module!\n"
      "  %call = call i32 @foo2()\n"
      "; ModuleID = 'M1'\n"
      "i32 ()* @foo2\n"
      "; ModuleID = 'M2'\n"));

  Error.clear();
  EXPECT_TRUE(verifyModule(M3, &ErrorOS));
  EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
      "Referencing personality function in another module!"));

  // Erase bad methods to avoid triggering an assertion failure on destruction
  F1->eraseFromParent();
  F3->eraseFromParent();
}

TEST(VerifierTest, CrossModuleMetadataRef) {
  LLVMContext C;
  Module M1("M1", C);
  Module M2("M2", C);
  GlobalVariable *newGV =
      new GlobalVariable(M1, Type::getInt8Ty(C), false,
                         GlobalVariable::ExternalLinkage, nullptr,
                         "Some Global");

  DIBuilder dbuilder(M2);
  auto CU = dbuilder.createCompileUnit(dwarf::DW_LANG_Julia, "test.jl", ".",
                                       "unittest", false, "", 0);
  auto File = dbuilder.createFile("test.jl", ".");
  auto Ty = dbuilder.createBasicType("Int8", 8, 8, dwarf::DW_ATE_signed);
  dbuilder.createGlobalVariable(CU, "_SOME_GLOBAL", "_SOME_GLOBAL", File, 1, Ty,
                                false, newGV);
  dbuilder.finalize();

  std::string Error;
  raw_string_ostream ErrorOS(Error);
  EXPECT_TRUE(verifyModule(M2, &ErrorOS));
  EXPECT_TRUE(StringRef(ErrorOS.str())
                  .startswith("Referencing global in another module!"));
}

TEST(VerifierTest, InvalidVariableLinkage) {
  LLVMContext C;
  Module M("M", C);
  new GlobalVariable(M, Type::getInt8Ty(C), false,
                     GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global");
  std::string Error;
  raw_string_ostream ErrorOS(Error);
  EXPECT_TRUE(verifyModule(M, &ErrorOS));
  EXPECT_TRUE(
      StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
                                          "have external or weak linkage!"));
}

TEST(VerifierTest, InvalidFunctionLinkage) {
  LLVMContext C;
  Module M("M", C);

  FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
  Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M);
  std::string Error;
  raw_string_ostream ErrorOS(Error);
  EXPECT_TRUE(verifyModule(M, &ErrorOS));
  EXPECT_TRUE(
      StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
                                          "have external or weak linkage!"));
}

#ifndef _MSC_VER
// FIXME: This test causes an ICE in MSVC 2013.
TEST(VerifierTest, StripInvalidDebugInfo) {
  LLVMContext C;
  Module M("M", C);
  DIBuilder DIB(M);
  DIB.createCompileUnit(dwarf::DW_LANG_C89, "broken.c", "/",
                        "unittest", false, "", 0);
  DIB.finalize();
  EXPECT_FALSE(verifyModule(M));

  // Now break it.
  auto *File = DIB.createFile("not-a-CU.f", ".");
  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
  NMD->addOperand(File);
  EXPECT_TRUE(verifyModule(M));

  ModulePassManager MPM(true);
  MPM.addPass(VerifierPass(false));
  ModuleAnalysisManager MAM(true);
  MAM.registerPass([&] { return VerifierAnalysis(); });
  MPM.run(M, MAM);
  EXPECT_FALSE(verifyModule(M));
}
#endif

TEST(VerifierTest, StripInvalidDebugInfoLegacy) {
  LLVMContext C;
  Module M("M", C);
  DIBuilder DIB(M);
  DIB.createCompileUnit(dwarf::DW_LANG_C89, "broken.c", "/",
                        "unittest", false, "", 0);
  DIB.finalize();
  EXPECT_FALSE(verifyModule(M));

  // Now break it.
  auto *File = DIB.createFile("not-a-CU.f", ".");
  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
  NMD->addOperand(File);
  EXPECT_TRUE(verifyModule(M));

  legacy::PassManager Passes;
  Passes.add(createVerifierPass(false));
  Passes.run(M);
  EXPECT_FALSE(verifyModule(M));
}

} // end anonymous namespace
} // end namespace llvm
