xref: /llvm-project/mlir/unittests/IR/Diagnostic.cpp (revision e511026bf04b9d10d91d107174037b48f531278a)
1*e511026bSAndrew Luo //===- Diagnostic.cpp - Dialect unit tests -------------------------------===//
2*e511026bSAndrew Luo //
3*e511026bSAndrew Luo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e511026bSAndrew Luo // See https://llvm.org/LICENSE.txt for license information.
5*e511026bSAndrew Luo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e511026bSAndrew Luo //
7*e511026bSAndrew Luo //===----------------------------------------------------------------------===//
8*e511026bSAndrew Luo 
9*e511026bSAndrew Luo #include "mlir/IR/Diagnostics.h"
10*e511026bSAndrew Luo #include "mlir/Support/TypeID.h"
11*e511026bSAndrew Luo #include "gtest/gtest.h"
12*e511026bSAndrew Luo 
13*e511026bSAndrew Luo using namespace mlir;
14*e511026bSAndrew Luo using namespace mlir::detail;
15*e511026bSAndrew Luo 
16*e511026bSAndrew Luo namespace {
17*e511026bSAndrew Luo 
18*e511026bSAndrew Luo TEST(DiagnosticLifetime, TestCopiesConstCharStar) {
19*e511026bSAndrew Luo   const auto *expectedMessage = "Error 1, don't mutate this";
20*e511026bSAndrew Luo 
21*e511026bSAndrew Luo   // Copy expected message into a mutable container, and call the constructor.
22*e511026bSAndrew Luo   std::string myStr(expectedMessage);
23*e511026bSAndrew Luo 
24*e511026bSAndrew Luo   mlir::MLIRContext context;
25*e511026bSAndrew Luo   Diagnostic diagnostic(mlir::UnknownLoc::get(&context),
26*e511026bSAndrew Luo                         DiagnosticSeverity::Note);
27*e511026bSAndrew Luo   diagnostic << myStr.c_str();
28*e511026bSAndrew Luo 
29*e511026bSAndrew Luo   // Mutate underlying pointer, but ensure diagnostic still has orig. message
30*e511026bSAndrew Luo   myStr[0] = '^';
31*e511026bSAndrew Luo 
32*e511026bSAndrew Luo   std::string resultMessage;
33*e511026bSAndrew Luo   llvm::raw_string_ostream stringStream(resultMessage);
34*e511026bSAndrew Luo   diagnostic.print(stringStream);
35*e511026bSAndrew Luo   ASSERT_STREQ(expectedMessage, resultMessage.c_str());
36*e511026bSAndrew Luo }
37*e511026bSAndrew Luo 
38*e511026bSAndrew Luo TEST(DiagnosticLifetime, TestLazyCopyStringLiteral) {
39*e511026bSAndrew Luo   char charArr[21] = "Error 1, mutate this";
40*e511026bSAndrew Luo   mlir::MLIRContext context;
41*e511026bSAndrew Luo   Diagnostic diagnostic(mlir::UnknownLoc::get(&context),
42*e511026bSAndrew Luo                         DiagnosticSeverity::Note);
43*e511026bSAndrew Luo 
44*e511026bSAndrew Luo   // Diagnostic contains optimization which assumes string literals are
45*e511026bSAndrew Luo   // represented by `const char[]` type. This is imperfect as we can sometimes
46*e511026bSAndrew Luo   // trick the type system as seen below.
47*e511026bSAndrew Luo   //
48*e511026bSAndrew Luo   // Still we use this to check the diagnostic is lazily storing the pointer.
49*e511026bSAndrew Luo   auto addToDiagnosticAsConst = [&diagnostic](const char(&charArr)[21]) {
50*e511026bSAndrew Luo     diagnostic << charArr;
51*e511026bSAndrew Luo   };
52*e511026bSAndrew Luo   addToDiagnosticAsConst(charArr);
53*e511026bSAndrew Luo 
54*e511026bSAndrew Luo   // Mutate the underlying pointer and ensure the string does change
55*e511026bSAndrew Luo   charArr[0] = '^';
56*e511026bSAndrew Luo 
57*e511026bSAndrew Luo   std::string resultMessage;
58*e511026bSAndrew Luo   llvm::raw_string_ostream stringStream(resultMessage);
59*e511026bSAndrew Luo   diagnostic.print(stringStream);
60*e511026bSAndrew Luo   ASSERT_STREQ("^rror 1, mutate this", resultMessage.c_str());
61*e511026bSAndrew Luo }
62*e511026bSAndrew Luo 
63*e511026bSAndrew Luo } // namespace
64